Merge branch 'i915tex_privbuffers' into softpipe_0_1_branch
authorKeith Whitwell <keith@tungstengraphics.com>
Tue, 31 Jul 2007 13:37:45 +0000 (14:37 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Tue, 31 Jul 2007 13:37:45 +0000 (14:37 +0100)
Conflicts:

src/mesa/drivers/dri/i915tex/intel_buffers.c
src/mesa/drivers/dri/i915tex/intel_context.c
src/mesa/drivers/dri/i915tex/intel_fbo.c
src/mesa/drivers/dri/i915tex/intel_pixel_draw.c

321 files changed:
Makefile
Makefile.mgw
configs/config.mgw [new file with mode: 0644]
configs/linux-dri
docs/README.MINGW32
include/GL/gl.h
include/GL/glut.h
include/GL/mesa_wgl.h
progs/demos/geartrain.c
progs/demos/gltestperf.c
progs/demos/isosurf.c
progs/demos/morph3d.c
progs/demos/winpos.c
progs/fbdev/glfbdevtest.c
progs/osdemos/ostest1.c
progs/samples/Makefile.mgw
progs/samples/prim.c
progs/trivial/Makefile
progs/trivial/clear.c
progs/trivial/dlist-dangling.c
progs/trivial/dlist-edgeflag-dangling.c
progs/trivial/dlist-edgeflag.c
progs/trivial/fs-tri.c [new file with mode: 0644]
progs/trivial/line-clip.c
progs/trivial/line-cull.c
progs/trivial/line-userclip-clip.c
progs/trivial/line-userclip-nop-clip.c
progs/trivial/line-userclip-nop.c
progs/trivial/line-userclip.c
progs/trivial/line.c
progs/trivial/lineloop-clip.c
progs/trivial/lineloop.c
progs/trivial/point-clip.c
progs/trivial/point-param.c
progs/trivial/point-wide.c
progs/trivial/point.c
progs/trivial/poly-flat.c
progs/trivial/poly-unfilled.c
progs/trivial/poly.c
progs/trivial/quad-clip-all-vertices.c
progs/trivial/quad-clip-nearplane.c
progs/trivial/quad-clip.c
progs/trivial/quad-degenerate.c
progs/trivial/quad-flat.c
progs/trivial/quad-offset-factor.c
progs/trivial/quad-offset-unfilled.c
progs/trivial/quad-offset-units.c
progs/trivial/quad-tex-3d.c
progs/trivial/quad-unfilled.c
progs/trivial/quads.c
progs/trivial/quadstrip-flat.c
progs/trivial/quadstrip.c
progs/trivial/tri-blend.c
progs/trivial/tri-clip.c
progs/trivial/tri-cull.c
progs/trivial/tri-dlist.c
progs/trivial/tri-edgeflag.c
progs/trivial/tri-flat-clip.c
progs/trivial/tri-flat.c
progs/trivial/tri-tex-3d.c
progs/trivial/tri-unfilled-clip.c
progs/trivial/tri-unfilled-smooth.c
progs/trivial/tri-unfilled-userclip.c
progs/trivial/tri-unfilled.c
progs/trivial/tri-userclip.c
progs/trivial/tri-z.c [new file with mode: 0644]
progs/trivial/tri.c
progs/trivial/tristrip.c
progs/xdemos/offset.c
progs/xdemos/pbdemo.c
src/glu/sgi/Makefile.mgw [new file with mode: 0644]
src/glu/sgi/libnurbs/interface/glcurveval.h
src/glu/sgi/libnurbs/interface/glsurfeval.cc
src/glu/sgi/libnurbs/interface/glsurfeval.h
src/glut/glx/Makefile.mgw [new file with mode: 0644]
src/glut/glx/glut_fbc.c
src/glut/glx/glutint.h
src/glut/glx/win32_winproc.c
src/mesa/Makefile.mgw
src/mesa/drivers/dri/Makefile.template
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/i810/i810state.c
src/mesa/drivers/dri/i810/i810tris.c
src/mesa/drivers/dri/i915/i915_vtbl.c
src/mesa/drivers/dri/i915/intel_pixel.c
src/mesa/drivers/dri/i915tex/Makefile
src/mesa/drivers/dri/i915tex/i915_context.c
src/mesa/drivers/dri/i915tex/i915_vtbl.c
src/mesa/drivers/dri/i915tex/intel_buffers.c
src/mesa/drivers/dri/i915tex/intel_context.c
src/mesa/drivers/dri/i915tex/intel_fbo.c
src/mesa/drivers/dri/i915tex/intel_fbo.h
src/mesa/drivers/dri/i915tex/intel_surface.c [new file with mode: 0644]
src/mesa/drivers/dri/i965/brw_sf_state.c
src/mesa/drivers/dri/i965/intel_blit.c
src/mesa/drivers/dri/i965/intel_blit.h
src/mesa/drivers/dri/i965/intel_pixel_bitmap.c
src/mesa/drivers/dri/mach64/mach64_native_vb.c
src/mesa/drivers/dri/mach64/mach64_tris.c
src/mesa/drivers/dri/mga/mgatris.c
src/mesa/drivers/dri/nouveau/nouveau_buffers.c
src/mesa/drivers/dri/nouveau/nouveau_context.c
src/mesa/drivers/dri/nouveau/nouveau_context.h
src/mesa/drivers/dri/nouveau/nouveau_driver.c
src/mesa/drivers/dri/nouveau/nouveau_fifo.c
src/mesa/drivers/dri/nouveau/nouveau_lock.c
src/mesa/drivers/dri/nouveau/nouveau_object.c
src/mesa/drivers/dri/nouveau/nouveau_screen.c
src/mesa/drivers/dri/nouveau/nouveau_state.c
src/mesa/drivers/dri/nouveau/nouveau_sync.c
src/mesa/drivers/dri/nouveau/nouveau_sync.h
src/mesa/drivers/dri/nouveau/nv10_state.c
src/mesa/drivers/dri/nouveau/nv10_swtcl.c
src/mesa/drivers/dri/nouveau/nv20_state.c
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_emit.c
src/mesa/drivers/dri/r300/r300_reg.h
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r300/r300_vertprog.c
src/mesa/drivers/dri/r300/r300_vertprog.h
src/mesa/drivers/dri/savage/savagetris.c
src/mesa/drivers/dri/tdfx/tdfx_tris.c
src/mesa/drivers/fbdev/glfbdev.c
src/mesa/drivers/windows/gdi/wgl.c
src/mesa/drivers/windows/gdi/wmesa.c
src/mesa/drivers/windows/gdi/wmesadef.h
src/mesa/drivers/x11/Makefile [new file with mode: 0644]
src/mesa/drivers/x11/fakeglx.c
src/mesa/drivers/x11/xm_api.c
src/mesa/drivers/x11/xm_buffer.c
src/mesa/drivers/x11/xm_dd.c
src/mesa/drivers/x11/xm_span.c
src/mesa/drivers/x11/xm_surface.c [new file with mode: 0644]
src/mesa/drivers/x11/xm_tri.c
src/mesa/drivers/x11/xmesaP.h
src/mesa/main/api_arrayelt.c
src/mesa/main/api_loopback.c
src/mesa/main/api_noop.c
src/mesa/main/api_validate.c
src/mesa/main/arrayobj.c
src/mesa/main/context.c
src/mesa/main/context.h
src/mesa/main/dlist.c
src/mesa/main/execmem.c
src/mesa/main/framebuffer.c
src/mesa/main/glheader.h
src/mesa/main/hash.c
src/mesa/main/image.c
src/mesa/main/image.h
src/mesa/main/imports.c
src/mesa/main/imports.h
src/mesa/main/lines.c
src/mesa/main/mtypes.h
src/mesa/main/points.c
src/mesa/main/queryobj.c
src/mesa/main/renderbuffer.c
src/mesa/main/shaders.c
src/mesa/main/state.c
src/mesa/main/texcompress_fxt1.c
src/mesa/main/texenvprogram.c
src/mesa/main/teximage.c
src/mesa/main/texstore.c
src/mesa/main/varray.c
src/mesa/main/vtxfmt_tmp.h
src/mesa/math/m_eval.c
src/mesa/math/m_eval.h
src/mesa/math/m_translate.h
src/mesa/math/m_xform.c
src/mesa/pipe/Makefile [new file with mode: 0644]
src/mesa/pipe/draw/draw_clip.c [new file with mode: 0644]
src/mesa/pipe/draw/draw_context.c [new file with mode: 0644]
src/mesa/pipe/draw/draw_context.h [new file with mode: 0644]
src/mesa/pipe/draw/draw_cull.c [new file with mode: 0644]
src/mesa/pipe/draw/draw_flatshade.c [new file with mode: 0644]
src/mesa/pipe/draw/draw_offset.c [new file with mode: 0644]
src/mesa/pipe/draw/draw_private.h [new file with mode: 0644]
src/mesa/pipe/draw/draw_twoside.c [new file with mode: 0644]
src/mesa/pipe/draw/draw_unfilled.c [new file with mode: 0644]
src/mesa/pipe/draw/draw_vb.c [new file with mode: 0644]
src/mesa/pipe/p_context.h [new file with mode: 0644]
src/mesa/pipe/p_defines.h [new file with mode: 0644]
src/mesa/pipe/p_state.h [new file with mode: 0644]
src/mesa/pipe/softpipe/Makefile [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_clear.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_clear.h [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_context.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_context.h [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_headers.h [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_prim_setup.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_prim_setup.h [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad.h [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_alpha_test.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_blend.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_bufloop.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_colormask.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_coverage.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_depth_test.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_fs.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_occlusion.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_output.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_stencil.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_quad_stipple.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_state.h [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_state_blend.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_state_clip.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_state_derived.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_state_fs.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_state_sampler.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_state_setup.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_state_surface.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_surface.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_surface.h [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_z_surface.c [new file with mode: 0644]
src/mesa/pipe/softpipe/sp_z_surface.h [new file with mode: 0644]
src/mesa/pipe/tgsi/Makefile [new file with mode: 0644]
src/mesa/pipe/tgsi/core/Makefile [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_build.c [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_build.h [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_core.h [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_dump.c [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_dump.h [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_exec.c [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_exec.h [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_parse.c [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_parse.h [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_token.h [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_util.c [new file with mode: 0644]
src/mesa/pipe/tgsi/core/tgsi_util.h [new file with mode: 0644]
src/mesa/pipe/tgsi/mesa/Makefile [new file with mode: 0644]
src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c [new file with mode: 0644]
src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.h [new file with mode: 0644]
src/mesa/pipe/tgsi/mesa/tgsi_mesa.h [new file with mode: 0644]
src/mesa/pipe/tgsi/tgsi_platform.h [new file with mode: 0644]
src/mesa/shader/arbprogparse.c
src/mesa/shader/prog_execute.c
src/mesa/shader/program.c
src/mesa/shader/shader_api.c
src/mesa/shader/slang/slang_builtin.c
src/mesa/shader/slang/slang_builtin.h
src/mesa/shader/slang/slang_codegen.c
src/mesa/shader/slang/slang_compile.c
src/mesa/shader/slang/slang_emit.c
src/mesa/shader/slang/slang_ir.c
src/mesa/shader/slang/slang_ir.h
src/mesa/shader/slang/slang_label.h
src/mesa/shader/slang/slang_link.c
src/mesa/shader/slang/slang_preprocess.c
src/mesa/shader/slang/slang_typeinfo.c
src/mesa/shader/slang/slang_vartable.c
src/mesa/sources
src/mesa/state_tracker/Makefile [new file with mode: 0644]
src/mesa/state_tracker/st_atom.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom.h [new file with mode: 0644]
src/mesa/state_tracker/st_atom_alphatest.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_blend.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_cbuf.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_clear_color.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_clip.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_depth.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_framebuffer.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_fs.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_sampler.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_scissor.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_setup.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_stencil.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_stipple.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_viewport.c [new file with mode: 0644]
src/mesa/state_tracker/st_atom_vs.c [new file with mode: 0644]
src/mesa/state_tracker/st_cb_program.c [new file with mode: 0644]
src/mesa/state_tracker/st_context.c [new file with mode: 0644]
src/mesa/state_tracker/st_context.h [new file with mode: 0644]
src/mesa/state_tracker/st_draw.c [new file with mode: 0644]
src/mesa/state_tracker/st_draw.h [new file with mode: 0644]
src/mesa/state_tracker/st_program.h [new file with mode: 0644]
src/mesa/state_tracker/st_public.h [new file with mode: 0644]
src/mesa/state_tracker/st_texobj.c [new file with mode: 0644]
src/mesa/state_tracker/st_texobj.h [new file with mode: 0644]
src/mesa/swrast/s_aalinetemp.h
src/mesa/swrast/s_atifragshader.c
src/mesa/swrast/s_context.c
src/mesa/swrast/s_context.h
src/mesa/swrast/s_drawpix.c
src/mesa/swrast/s_fragprog.c
src/mesa/swrast/s_lines.c
src/mesa/swrast/s_points.c
src/mesa/swrast/s_span.c
src/mesa/swrast/s_stencil.c
src/mesa/swrast/swrast.h
src/mesa/swrast_setup/ss_context.c
src/mesa/swrast_setup/ss_tritmp.h
src/mesa/tnl/t_context.c
src/mesa/tnl/t_context.h
src/mesa/tnl/t_pipeline.c
src/mesa/tnl/t_vb_program.c
src/mesa/tnl/t_vertex.c
src/mesa/tnl/t_vp_build.c
src/mesa/tnl/tnl.h
src/mesa/tnl_dd/t_dd_vb.c
src/mesa/vbo/vbo.h
src/mesa/vbo/vbo_context.c
src/mesa/vbo/vbo_exec.c
src/mesa/vbo/vbo_exec.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_exec_array.c
src/mesa/vbo/vbo_exec_draw.c
src/mesa/vbo/vbo_exec_eval.c
src/mesa/vbo/vbo_rebase.c
src/mesa/vbo/vbo_save.c
src/mesa/vbo/vbo_save.h
src/mesa/vbo/vbo_save_api.c
src/mesa/vbo/vbo_save_draw.c
src/mesa/vbo/vbo_save_loopback.c
src/mesa/vbo/vbo_split.c
src/mesa/vbo/vbo_split_copy.c
src/mesa/vbo/vbo_split_inplace.c
src/mesa/vf/vf.c [new file with mode: 0644]
src/mesa/vf/vf.h [new file with mode: 0644]
src/mesa/vf/vf_generic.c [new file with mode: 0644]
src/mesa/vf/vf_sse.c [new file with mode: 0644]

index ea86787cebe7aa0f84a2b18aede0ce4fd9fb1103..9a6557571c5029cf477ad2e9d44b41ff46d1cabf 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -288,17 +288,6 @@ MAIN_FILES = \
        $(DIRECTORY)/vms/analyze_map.com                                \
        $(DIRECTORY)/vms/xlib.opt                                       \
        $(DIRECTORY)/vms/xlib_share.opt                                 \
-       $(DIRECTORY)/windows/VC6/mesa/gdi/gdi.dsp                       \
-       $(DIRECTORY)/windows/VC6/mesa/glu/*.txt                         \
-       $(DIRECTORY)/windows/VC6/mesa/glu/glu.dsp                       \
-       $(DIRECTORY)/windows/VC6/mesa/mesa.dsw                          \
-       $(DIRECTORY)/windows/VC6/mesa/mesa/mesa.dsp                     \
-       $(DIRECTORY)/windows/VC6/mesa/osmesa/osmesa.dsp                 \
-       $(DIRECTORY)/windows/VC7/mesa/gdi/gdi.vcproj                    \
-       $(DIRECTORY)/windows/VC7/mesa/glu/glu.vcproj                    \
-       $(DIRECTORY)/windows/VC7/mesa/mesa.sln                          \
-       $(DIRECTORY)/windows/VC7/mesa/mesa/mesa.vcproj                  \
-       $(DIRECTORY)/windows/VC7/mesa/osmesa/osmesa.vcproj              \
        $(DIRECTORY)/windows/VC8/mesa/mesa.sln                          \
        $(DIRECTORY)/windows/VC8/mesa/gdi/gdi.vcproj                    \
        $(DIRECTORY)/windows/VC8/mesa/glu/glu.vcproj                    \
@@ -328,6 +317,7 @@ SGI_GLU_FILES = \
        $(DIRECTORY)/src/glu/Makefile                                   \
        $(DIRECTORY)/src/glu/descrip.mms                                \
        $(DIRECTORY)/src/glu/sgi/Makefile                               \
+       $(DIRECTORY)/src/glu/sgi/Makefile.mgw                           \
        $(DIRECTORY)/src/glu/sgi/Makefile.win                           \
        $(DIRECTORY)/src/glu/sgi/Makefile.DJ                            \
        $(DIRECTORY)/src/glu/sgi/glu.def                                \
@@ -372,6 +362,8 @@ DEMO_FILES = \
        $(DIRECTORY)/progs/demos/*.cxx                  \
        $(DIRECTORY)/progs/demos/*.dat                  \
        $(DIRECTORY)/progs/demos/README                 \
+       $(DIRECTORY)/progs/fbdev/Makefile               \
+       $(DIRECTORY)/progs/fbdev/glfbdevtest.c          \
        $(DIRECTORY)/progs/osdemos/Makefile             \
        $(DIRECTORY)/progs/osdemos/*.c                  \
        $(DIRECTORY)/progs/xdemos/Makefile*             \
index 948860890c05510d7b6bd1d6d72eeebc2858f46c..3dc9f626438cafa5e5a5c281942be2725762222c 100644 (file)
 
 # MinGW core makefile updated for Mesa 7.0
 #
-#  updated : by Heromyth, 2007-6-25
+#  Updated : by Heromyth, on 2007-7-21
 #  Email   : zxpmyth@yahoo.com.cn
-#  Bug     : All the default settings work fine. But the setting X86=1 can't work. 
+#  Bugs    : 1) All the default settings work fine. But the setting X86=1 can't work. 
 #            The others havn't been tested yet.
-
+#            2) The generated DLLs are *not* compatible with the ones built
+#            with the other compilers like VC8, especially for GLUT. 
+#            3) MAlthough more tests are needed, it can be used individually!
 
 
 .PHONY : all libgl clean realclean
@@ -73,13 +75,14 @@ CFLAGS += -O2 -ffast-math
 
 export CFLAGS
 
+
 ifeq ($(wildcard $(addsuffix /rm.exe,$(subst ;, ,$(PATH)))),)
 UNLINK = del $(subst /,\,$(1))
 else
 UNLINK = $(RM) $(1)
 endif
 
-all: libgl libglu libglut
+all: libgl libglu libglut example
 
 libgl: lib
        $(MAKE) -f Makefile.mgw -C src/mesa
diff --git a/configs/config.mgw b/configs/config.mgw
new file mode 100644 (file)
index 0000000..b961eb9
--- /dev/null
@@ -0,0 +1,42 @@
+# MinGW config include file updated for Mesa 7.0\r
+#\r
+#  Updated : by Heromyth, on 2007-7-21\r
+#  Email   : zxpmyth@yahoo.com.cn\r
+#  Bugs    : 1) All the default settings work fine. But the setting X86=1 can't work. \r
+#            The others havn't been tested yet.\r
+#            2) The generated DLLs are *not* compatible with the ones built\r
+#            with the other compilers like VC8, especially for GLUT. \r
+#            3) Although more tests are needed, it can be used individually!\r
+\r
+# The generated DLLs by MingW with STDCALL are not totally compatible \r
+# with the ones linked by Microsoft's compilers.\r
+#\r
+# xxx_USING_STDCALL = 1          Compiling MESA with __stdcall. This is default!\r
+# \r
+# xxx_USING_STDCALL = 0          Compiling MESA without __stdcall. I like this:)\r
+#  \r
+\r
+# In fact, GL_USING_STDCALL and GLUT_USING_STDCALL can be\r
+# different. For example:\r
+#\r
+#   GL_USING_STDCALL = 0\r
+#   GLUT_USING_STDCALL = 1\r
+# \r
+# Suggested setting:\r
+#\r
+#     ALL_USING_STDCALL = 1\r
+#\r
+# That's default!\r
+#\r
+\r
+\r
+ALL_USING_STDCALL = 1\r
+\r
+\r
+ifeq ($(ALL_USING_STDCALL),1)\r
+  GL_USING_STDCALL = 1\r
+  GLUT_USING_STDCALL = 1\r
+else\r
+  GL_USING_STDCALL = 0\r
+  GLUT_USING_STDCALL = 0\r
+endif\r
index 5f945a73f1a4c5df4725a2eacd8098bcb49b289b..4af8c25f66f869b0c85cdc6b5db45eefc0b40be2 100644 (file)
@@ -66,5 +66,4 @@ WINDOW_SYSTEM=dri
 
 # gamma are missing because they have not been converted to use the new
 # interface.
-DRI_DIRS = i810 i915tex i915 i965 mach64 mga r128 r200 r300 radeon s3v \
-       savage sis tdfx trident unichrome ffb
+DRI_DIRS = i915tex 
index 2b39f120908a0a040386b2d88acc6a11f491bd59..138dd43eaccfe0d3b3ddc6f308ae800f0ee3624d 100644 (file)
@@ -88,3 +88,52 @@ Running the Build:
 
                Paul G. <pgarceau@users.sourceforge.net>
                Daniel Borca <dborca@users.sourceforge.net>
+
+
+
+*******************This section is added by Heromyth*****************************
+Updated on 2007-7-21, by Heromyth <zxpmyth@yahoo.com.cn>
+
+
+Notice:
+       1) The generated DLLs are *not* compatible with the ones built
+with the other compilers like VC8, especially for GLUT. 
+
+       2) Although more tests are needed, it can be used individually!
+
+       3) You can set the options about whether using STDCALL to build MESA. The 
+config file is <Mesa3D-root>\configs\config.mgw. The default setting is that:
+               ALL_USING_STDCALL = 1
+, which means using STDCALL to build MESA. 
+
+       4) Of course, you can MESA without using STDCALL,I like this:) 
+The setting is :
+               ALL_USING_STDCALL = 0
+To do this, however, you must modify wingdi.h which is in MingW's include dir. 
+For example, run:
+       notepad C:\MingW\include\wingdi.h
+, and delete all the lines where all the wgl*() functions are. Because they would 
+be conflicted with the ones in <Mesa3D-root>\include\GL\mesa_wgl.h.
+
+======= Conflicted Functions List ======
+WINGDIAPI BOOL WINAPI wglCopyContext(HGLRC,HGLRC,UINT);
+WINGDIAPI HGLRC WINAPI wglCreateContext(HDC);
+WINGDIAPI HGLRC WINAPI wglCreateLayerContext(HDC,int);
+WINGDIAPI BOOL WINAPI wglDeleteContext(HGLRC);
+WINGDIAPI BOOL WINAPI wglDescribeLayerPlane(HDC,int,int,UINT,LPLAYERPLANEDESCRIPTOR);
+WINGDIAPI HGLRC WINAPI wglGetCurrentContext(void);
+WINGDIAPI HDC WINAPI wglGetCurrentDC(void);
+WINGDIAPI int WINAPI wglGetLayerPaletteEntries(HDC,int,int,int,COLORREF*);
+WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR);
+WINGDIAPI BOOL WINAPI wglMakeCurrent(HDC,HGLRC);
+WINGDIAPI BOOL WINAPI wglRealizeLayerPalette(HDC,int,BOOL);
+WINGDIAPI int WINAPI wglSetLayerPaletteEntries(HDC,int,int,int,const COLORREF*);
+WINGDIAPI BOOL WINAPI wglShareLists(HGLRC,HGLRC);
+WINGDIAPI BOOL WINAPI wglSwapLayerBuffers(HDC,UINT);
+WINGDIAPI BOOL WINAPI wglUseFontBitmapsA(HDC,DWORD,DWORD,DWORD);
+WINGDIAPI BOOL WINAPI wglUseFontBitmapsW(HDC,DWORD,DWORD,DWORD);
+WINGDIAPI BOOL WINAPI wglUseFontOutlinesA(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT);
+WINGDIAPI BOOL WINAPI wglUseFontOutlinesW(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT);
+===================
+
+*********************************************************************************
\ No newline at end of file
index a388de36e4995ed1fa8839d277a50483401f68c7..09195aa136108ca1859a3aa3e30ab26af64127bf 100644 (file)
 #  else /* for use with static link lib build of Win32 edition only */
 #    define GLAPI extern
 #  endif /* _STATIC_MESA support */
-#  define GLAPIENTRY __stdcall
+#  if defined(__MINGW32__) && defined(GL_NO_STDCALL)  /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */
+#    define GLAPIENTRY 
+#  else
+#    define GLAPIENTRY __stdcall
+#  endif
 #elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */
 #  define GLAPI extern
 #  define GLAPIENTRY __stdcall
@@ -84,7 +88,8 @@
 #include <windows.h>
 #endif
 
-#if defined(_WIN32) && !defined(_WINGDI_) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(_WINGDI_) && !defined(_GNU_H_WINDOWS32_DEFINES) \
+     && !defined(OPENSTEP) && !defined(__CYGWIN__) || defined(__MINGW32__)
 #include <GL/mesa_wgl.h>
 #endif
 
@@ -2161,11 +2166,11 @@ typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLsh
 #define GL_DEBUG_PRINT_MESA               0x875A
 #define GL_DEBUG_ASSERT_MESA              0x875B
 
-GLAPI GLhandleARB APIENTRY glCreateDebugObjectMESA (void);
-GLAPI void APIENTRY glClearDebugLogMESA (GLhandleARB obj, GLenum logType, GLenum shaderType);
-GLAPI void APIENTRY glGetDebugLogMESA (GLhandleARB obj, GLenum logType, GLenum shaderType, GLsizei maxLength,
+GLAPI GLhandleARB GLAPIENTRY glCreateDebugObjectMESA (void);
+GLAPI void GLAPIENTRY glClearDebugLogMESA (GLhandleARB obj, GLenum logType, GLenum shaderType);
+GLAPI void GLAPIENTRY glGetDebugLogMESA (GLhandleARB obj, GLenum logType, GLenum shaderType, GLsizei maxLength,
                                          GLsizei *length, GLcharARB *debugLog);
-GLAPI GLsizei APIENTRY glGetDebugLogLengthMESA (GLhandleARB obj, GLenum logType, GLenum shaderType);
+GLAPI GLsizei GLAPIENTRY glGetDebugLogLengthMESA (GLhandleARB obj, GLenum logType, GLenum shaderType);
 
 #endif /* GL_MESA_shader_debug */
 
index e0fad6e5cb08b039520f06b1d094e7746765566d..e286349f9b01c3903b4f9104c9aaf36ba1531661 100644 (file)
 #include <GL/gl.h>
 #include <GL/glu.h>
 
+#if defined(__MINGW32__)
+#include <GL/mesa_wgl.h>
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -108,7 +112,7 @@ extern _CRTIMP void __cdecl exit(int);
    and redifinition of Windows system defs, also removes requirement of
    pretty much any standard windows header from this file */
 
-#if (_MSC_VER >= 800) || defined(__MINGW32__) || defined(_STDCALL_SUPPORTED) || defined(__CYGWIN32__)
+#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__CYGWIN32__)
 #      define GLUTAPIENTRY __stdcall
 #else
 #      define GLUTAPIENTRY
@@ -130,8 +134,9 @@ extern _CRTIMP void __cdecl exit(int);
 #              pragma message( "----: being multiply defined you should include WINDOWS.H priot to gl/glut.h" )
 #      endif
 #      define CALLBACK __stdcall
-typedef int (GLUTAPIENTRY *PROC)();
+
 #if !defined(__MINGW32__)
+       typedef int (GLUTAPIENTRY *PROC)();
        typedef void *HGLRC;
        typedef void *HDC;
 #endif
index acc7eac2a718a41f23bd392514597d5e89ab0f01..1d774571d94db40dfb08160961a83df01a9d5795 100644 (file)
 /* prototypes for the Mesa WGL functions */
 /* relocated here so that I could make GLUT get them properly */
 
-#define _mesa_wgl_h_
-
 #ifndef _mesa_wgl_h_
 #define _mesa_wgl_h_
 
+#if defined(__MINGW32__)
+#  define __W32API_USE_DLLIMPORT__
+#endif
 
 #include <GL/gl.h>
 
@@ -39,23 +40,16 @@ extern "C" {
 #endif
 
 
-#if !defined(OPENSTEP) && (defined(__WIN32__) || defined(__CYGWIN32__))
-#  if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */
-#    define GLAPI __declspec(dllexport)
-#    define WGLAPI __declspec(dllexport)
-#  elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */
-#    define GLAPI __declspec(dllimport)
-#    define WGLAPI __declspec(dllimport)
-#  else /* for use with static link lib build of Win32 edition only */
-#    define GLAPI extern
-#    define WGLAPI __declspec(dllimport)
-#  endif /* _STATIC_MESA support */
-#  define GLAPIENTRY __stdcall
-#else
-/* non-Windows compilation */
-#  define GLAPI extern
-#  define GLAPIENTRY
-#endif /* WIN32 / CYGWIN32 bracket */
+#ifndef WGLAPI
+#define WGLAPI GLAPI
+#endif
+
+#if defined(__MINGW32__)
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN 1
+#  endif
+#  include <windows.h>
+#endif
 
 
 #if defined(_WIN32) && !defined(_WINGDI_) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP)
@@ -80,23 +74,25 @@ typedef struct tagPIXELFORMATDESCRIPTOR PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESC
 #  pragma warning( disable : 4273 ) /* 'function' : inconsistent DLL linkage. dllexport assumed. */
 #endif
 
-WGLAPI int   GLAPIENTRY wglDeleteContext(HGLRC);
-WGLAPI int   GLAPIENTRY wglMakeCurrent(HDC,HGLRC);
+
 WGLAPI int   GLAPIENTRY wglSetPixelFormat(HDC, int, const PIXELFORMATDESCRIPTOR *);
 WGLAPI int   GLAPIENTRY wglSwapBuffers(HDC hdc);
-WGLAPI HDC   GLAPIENTRY wglGetCurrentDC(void);
-WGLAPI HGLRC GLAPIENTRY wglCreateContext(HDC);
-WGLAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC,int);
-WGLAPI HGLRC GLAPIENTRY wglGetCurrentContext(void);
-WGLAPI PROC  GLAPIENTRY wglGetProcAddress(const char*);
 WGLAPI int   GLAPIENTRY wglChoosePixelFormat(HDC, const PIXELFORMATDESCRIPTOR *);
+WGLAPI int   GLAPIENTRY wglDescribePixelFormat(HDC,int, unsigned int, LPPIXELFORMATDESCRIPTOR);
+WGLAPI int   GLAPIENTRY wglGetPixelFormat(HDC hdc);
+
+
+#if defined(GL_NO_STDCALL) || !defined(__MINGW32__)
 WGLAPI int   GLAPIENTRY wglCopyContext(HGLRC, HGLRC, unsigned int);
+WGLAPI HGLRC GLAPIENTRY wglCreateContext(HDC);
+WGLAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC,int);
 WGLAPI int   GLAPIENTRY wglDeleteContext(HGLRC);
 WGLAPI int   GLAPIENTRY wglDescribeLayerPlane(HDC, int, int, unsigned int,LPLAYERPLANEDESCRIPTOR);
-WGLAPI int   GLAPIENTRY wglDescribePixelFormat(HDC,int, unsigned int, LPPIXELFORMATDESCRIPTOR);
+WGLAPI HGLRC GLAPIENTRY wglGetCurrentContext(void);
+WGLAPI HDC   GLAPIENTRY wglGetCurrentDC(void);
 WGLAPI int   GLAPIENTRY wglGetLayerPaletteEntries(HDC, int, int, int,COLORREF *);
-WGLAPI int   GLAPIENTRY wglGetPixelFormat(HDC hdc);
-WGLAPI int   GLAPIENTRY wglMakeCurrent(HDC, HGLRC);
+WGLAPI PROC  GLAPIENTRY wglGetProcAddress(const char*);
+WGLAPI int   GLAPIENTRY wglMakeCurrent(HDC,HGLRC);
 WGLAPI int   GLAPIENTRY wglRealizeLayerPalette(HDC, int, int);
 WGLAPI int   GLAPIENTRY wglSetLayerPaletteEntries(HDC, int, int, int,const COLORREF *);
 WGLAPI int   GLAPIENTRY wglShareLists(HGLRC, HGLRC);
@@ -105,12 +101,15 @@ WGLAPI int   GLAPIENTRY wglUseFontBitmapsA(HDC, unsigned long, unsigned long, un
 WGLAPI int   GLAPIENTRY wglUseFontBitmapsW(HDC, unsigned long, unsigned long, unsigned long);
 WGLAPI int   GLAPIENTRY wglUseFontOutlinesA(HDC, unsigned long, unsigned long, unsigned long, float,float, int, LPGLYPHMETRICSFLOAT);
 WGLAPI int   GLAPIENTRY wglUseFontOutlinesW(HDC, unsigned long, unsigned long, unsigned long, float,float, int, LPGLYPHMETRICSFLOAT);
+#endif
+
+#ifndef __MINGW32__
 WGLAPI int   GLAPIENTRY SwapBuffers(HDC);
 WGLAPI int   GLAPIENTRY ChoosePixelFormat(HDC,const PIXELFORMATDESCRIPTOR *);
 WGLAPI int   GLAPIENTRY DescribePixelFormat(HDC,int,unsigned int,LPPIXELFORMATDESCRIPTOR);
 WGLAPI int   GLAPIENTRY GetPixelFormat(HDC);
 WGLAPI int   GLAPIENTRY SetPixelFormat(HDC,int,const PIXELFORMATDESCRIPTOR *);
-
+#endif
 
 #ifndef WGL_ARB_extensions_string
 #define WGL_ARB_extensions_string 1
index 3feb2a0524b4a182a212fac84fe89327c616e9bb..8363f2abc6d361ceb44fbde121cb40bf871093ef 100644 (file)
@@ -1053,6 +1053,7 @@ main (int argc, char *argv[])
     else
        file = argv[1];
 
+    glutInit(&argc, argv); 
     glutInitWindowPosition (0, 0);
     glutInitWindowSize(640,480);
     glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
index be953901014ecce4ad13257b494e2f92adb7ada3..2188b0241924034f42f545c3f45237df9b8b1462 100644 (file)
@@ -569,6 +569,7 @@ main(int ac, char **av)
    if (ac == 2)
       frontbuffer = 0;
 
+   glutInit(&ac, av);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(640, 480);
index 0710bc6047bad5a82dbfdff76e9f972d44e38b69..10f94b6ace236081c914ca8ca825490a190bdb3a 100644 (file)
@@ -1042,6 +1042,7 @@ int main(int argc, char **argv)
 
    read_surface( "isosurf.dat" );
 
+   glutInit( &argc, argv);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(400, 400);
 
index 162a6ff847eb18a2133968ff5230fb646bf87b34..6aca8270ff515a250505fc44759dbc2b0a674797 100644 (file)
@@ -826,7 +826,7 @@ static void pinit(void)
 
 }
 
-static void INIT(void)
+int main(int argc, char **argv)
 {
   printf("Morph 3D - Shows morphing platonic polyhedra\n");
   printf("Author: Marcelo Fernandes Vianna (vianna@cat.cbpf.br)\n\n");
@@ -841,6 +841,7 @@ static void INIT(void)
 
   object=1;
 
+  glutInit(&argc, argv);
   glutInitWindowPosition(0,0);
   glutInitWindowSize(640,480);
 
@@ -888,9 +889,3 @@ static void INIT(void)
   glutMainLoop();
   
 }
-
-int main(int argc, char **argv)
-{
-  INIT();
-  return(0);
-}
index 3a1a19ecdb919bead0f05d51f9cb3ce1943c2699..b58e33086434ec48f60d31672c4c1d21e8f502b0 100644 (file)
@@ -100,6 +100,7 @@ static void init( void )
 
 int main( int argc, char *argv[] )
 {
+   glutInit(&argc, argv);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(500, 500);
    glutInitDisplayMode( GLUT_RGB );
index a461c55e2f86337f457449b0c57f3ba6f6d6f0d1..6d9f80703027bcb1fe5e9680cde62e6636e30f39 100644 (file)
 #include <GL/glfbdev.h>
 #include <math.h>
 
-#define DEFAULT_DEPTH 8
+
+/**
+ * Choose one of these modes
+ */
+/*static const int XRes = 1280, YRes = 1024, Hz = 75;*/
+/*static const int XRes = 1280, YRes = 1024, Hz = 70;*/
+/*static const int XRes = 1280, YRes = 1024, Hz = 60;*/
+static const int XRes = 1024, YRes = 768, Hz = 70;
+
+static int DesiredDepth = 32;
+
+static int NumFrames = 100;
 
 static struct fb_fix_screeninfo FixedInfo;
 static struct fb_var_screeninfo VarInfo, OrigVarInfo;
-static int DesiredDepth = 0;
 static int OriginalVT = -1;
 static int ConsoleFD = -1;
 static int FrameBufferFD = -1;
@@ -227,7 +237,6 @@ initialize_fbdev( void )
    VarInfo = OrigVarInfo;
 
    /* set the depth, resolution, etc */
-   DesiredDepth = 32;
    if (DesiredDepth)
       VarInfo.bits_per_pixel = DesiredDepth;
 
@@ -251,16 +260,60 @@ initialize_fbdev( void )
       VarInfo.blue.length = 8;
       VarInfo.transp.length = 8;
    }
-   /* timing values taken from /etc/fb.modes (1280x1024 @ 75Hz) */
-   VarInfo.xres_virtual = VarInfo.xres = 1280;
-   VarInfo.yres_virtual = VarInfo.yres = 1024;
-   VarInfo.pixclock = 7408;
-   VarInfo.left_margin = 248;
-   VarInfo.right_margin = 16;
-   VarInfo.upper_margin = 38;
-   VarInfo.lower_margin = 1;
-   VarInfo.hsync_len = 144;
-   VarInfo.vsync_len = 3;
+
+   /* timing values taken from /etc/fb.modes */
+   if (XRes == 1280 && YRes == 1024) {
+      VarInfo.xres_virtual = VarInfo.xres = XRes;
+      VarInfo.yres_virtual = VarInfo.yres = YRes;
+      if (Hz == 75) {
+         VarInfo.pixclock = 7408;
+         VarInfo.left_margin = 248;
+         VarInfo.right_margin = 16;
+         VarInfo.upper_margin = 38;
+         VarInfo.lower_margin = 1;
+         VarInfo.hsync_len = 144;
+         VarInfo.vsync_len = 3;
+      }
+      else if (Hz == 70) {
+         VarInfo.pixclock = 7937;
+         VarInfo.left_margin = 216;
+         VarInfo.right_margin = 80;
+         VarInfo.upper_margin = 36;
+         VarInfo.lower_margin = 1;
+         VarInfo.hsync_len = 112;
+         VarInfo.vsync_len = 5;
+      }
+      else if (Hz == 60) {
+         VarInfo.pixclock = 9260;
+         VarInfo.left_margin = 248;
+         VarInfo.right_margin = 48;
+         VarInfo.upper_margin = 38;
+         VarInfo.lower_margin = 1;
+         VarInfo.hsync_len = 112;
+         VarInfo.vsync_len = 3;
+      }
+      else {
+         fprintf(stderr, "invalid rate for 1280x1024\n");
+         exit(1);
+      }
+   }
+   else if (XRes == 1024 && YRes == 768 && Hz == 70) {
+      VarInfo.xres_virtual = VarInfo.xres = XRes;
+      VarInfo.yres_virtual = VarInfo.yres = YRes;
+      if (Hz == 70) {
+         VarInfo.pixclock = 13334;
+         VarInfo.left_margin = 144;
+         VarInfo.right_margin = 24;
+         VarInfo.upper_margin = 29;
+         VarInfo.lower_margin = 3;
+         VarInfo.hsync_len = 136;
+         VarInfo.vsync_len = 6;
+      }
+      else {
+         fprintf(stderr, "invalid rate for 1024x768\n");
+         exit(1);
+      }
+   }
 
    VarInfo.xoffset = 0;
    VarInfo.yoffset = 0;
@@ -338,7 +391,7 @@ initialize_fbdev( void )
    printf("MMIOAddress = %p\n", MMIOAddress);
 
    /* try out some simple MMIO register reads */
-   if (1)
+   if (0)
    {
       typedef unsigned int CARD32;
       typedef unsigned char CARD8;
@@ -452,6 +505,7 @@ gltest( void )
    GLFBDevVisualPtr vis;
    int bytes, r, g, b, a;
    float ang;
+   int i;
 
    printf("GLFBDEV_VENDOR = %s\n", glFBDevGetString(GLFBDEV_VENDOR));
    printf("GLFBDEV_VERSION = %s\n", glFBDevGetString(GLFBDEV_VERSION));
@@ -491,13 +545,17 @@ gltest( void )
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
 
-   for (ang = 0; ang <= 180; ang += 15) {
+   printf("Drawing %d frames...\n", NumFrames);
+
+   ang = 0.0;
+   for (i = 0; i < NumFrames; i++) {
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       glPushMatrix();
       glRotatef(ang, 1, 0, 0);
       doughnut(1, 3, 40, 20);
       glPopMatrix();
       glFBDevSwapBuffers(buf);
+      ang += 15.0;
    }
 
    /* clean up */
@@ -510,12 +568,29 @@ gltest( void )
 }
 
 
+static void
+parse_args(int argc, char *argv[])
+{
+   int i;
+
+   for (i = 1; i < argc; i++) {
+      if (strcmp(argv[i], "-f") == 0) {
+         NumFrames = atoi(argv[i+1]);
+         i++;
+      }
+   }
+}
+
+
 int
 main( int argc, char *argv[] )
 {
    signal(SIGUSR1, signal_handler);  /* exit if someone tries a vt switch */
    signal(SIGSEGV, signal_handler);  /* catch segfaults */
 
+   parse_args(argc, argv);
+
+   printf("Setting mode to %d x %d @ %d Hz, %d bpp\n", XRes, YRes, Hz, DesiredDepth);
    initialize_fbdev();
    gltest();
    shutdown_fbdev();
index 001e3686162fbb2c03098098155621bae3c9cbc8..2c7adfc3537aeb8d0a422e462c892e8d61333db6 100644 (file)
@@ -409,6 +409,8 @@ test(GLenum type, GLint bits, const char *filename)
 
    printf("Rendering %d bit/channel image: %s\n", bits, filename);
 
+   OSMesaColorClamp(GL_TRUE);
+
    init_context();
    render_image();
    if (Gradient)
@@ -421,7 +423,7 @@ test(GLenum type, GLint bits, const char *filename)
    if (WriteFiles && filename != NULL) {
       if (type == GL_UNSIGNED_SHORT) {
          GLushort *buffer16 = (GLushort *) buffer;
-         GLubyte *buffer8 = malloc(WIDTH * HEIGHT * 4);
+         GLubyte *buffer8 = (GLubyte *) malloc(WIDTH * HEIGHT * 4);
          int i;
          for (i = 0; i < WIDTH * HEIGHT * 4; i++)
             buffer8[i] = buffer16[i] >> 8;
@@ -430,8 +432,9 @@ test(GLenum type, GLint bits, const char *filename)
       }
       else if (type == GL_FLOAT) {
          GLfloat *buffer32 = (GLfloat *) buffer;
-         GLubyte *buffer8 = malloc(WIDTH * HEIGHT * 4);
+         GLubyte *buffer8 = (GLubyte *) malloc(WIDTH * HEIGHT * 4);
          int i;
+         /* colors may be outside [0,1] so we need to clamp */
          for (i = 0; i < WIDTH * HEIGHT * 4; i++)
             buffer8[i] = (GLubyte) (buffer32[i] * 255.0);
          write_ppm(filename, buffer8, WIDTH, HEIGHT);
index 11935405783d9798a76045d1631fd23904ba0da3..3b2fd785def74956a484574461fe66b6ffaf1fa2 100644 (file)
 #  Email : dborca@users.sourceforge.net
 #  Web   : http://www.geocities.com/dborca
 
+# MinGW samples makefile updated for Mesa 7.0
+#
+#  Updated : by Heromyth, on 2007-7-21
+#  Email   : zxpmyth@yahoo.com.cn
+#  Bugs    : 1) All the default settings work fine. But the setting X86=1 can't work. 
+#            The others havn't been tested yet.
+#            2) The generated DLLs are *not* compatible with the ones built
+#            with the other compilers like VC8, especially for GLUT. 
+#            3) Although more tests are needed, it can be used individually!
 
 #
 #  Available options:
 
 TOP = ../..
 
+include $(TOP)/configs/config.mgw
+ALL_USING_STDCALL ?= 1
+GL_USING_STDCALL ?= 1
+GLUT_USING_STDCALL ?= 1
+
 CC = mingw32-gcc
-CFLAGS = -Wall -W -pedantic
+CFLAGS = -Wall -pedantic
 CFLAGS += -O2 -ffast-math
 CFLAGS += -I$(TOP)/include -I../util
 ifeq ($(FX),1)
-CFLAGS += -DFX
+  CFLAGS += -DFX
+endif
+
+CFLAGS += -DGLUT_DISABLE_ATEXIT_HACK
+
+ifeq ($(GL_USING_STDCALL),0)
+  CFLAGS += -DGL_NO_STDCALL
+endif
+
+ifeq ($(GLUT_USING_STDCALL),1)
+  CFLAGS += -D_STDCALL_SUPPORTED
+else
+  CFLAGS += -DGLUT_NO_STDCALL
 endif
-CFLAGS += -DGLUT_DISABLE_ATEXIT_HACK -D_STDCALL_SUPPORTED
-CFLAGS += -D_WINDEF_ -D_WINGDI_
+
 
 LD = mingw32-g++
 LDFLAGS = -s -L$(TOP)/lib
index 388e0153b4f2007b4e0ab34f422735df937062e3..f47c60faefd160bc6ebbfc275479a8d86e6f4c91 100644 (file)
@@ -466,7 +466,7 @@ static void Draw(void)
     } else {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
     }
-
+#if 01
     Viewport(0, 0); Point();
     Viewport(0, 1); Lines();
     Viewport(0, 2); LineStrip();
@@ -479,10 +479,12 @@ static void Draw(void)
     Viewport(1, 3); TriangleStrip();
 
     Viewport(2, 0); Rect();
+#endif
     Viewport(2, 1); PolygonFunc();
+#if 01
     Viewport(2, 2); Quads();
     Viewport(2, 3); QuadStrip();
-
+#endif
     glFlush();
 
     if (doubleBuffer) {
index 341c115c07d86e80c2cbee13c6fbaac5462c7695..2edf0ae0084b8d0dd99406dddfe64a44ca2a8582 100644 (file)
@@ -12,6 +12,7 @@ LIBS = $(APP_LIB_DEPS)
 
 SOURCES = \
        clear.c \
+       fs-tri.c \
        line-clip.c \
        line-cull.c \
        line-userclip-clip.c \
@@ -63,6 +64,7 @@ SOURCES = \
        tri-unfilled.c \
        tri-userclip.c \
        tri-dlist.c \
+       tri-z.c \
        tri.c \
        tristrip-clip.c \
        tristrip.c \
@@ -137,6 +139,11 @@ readtex.c: $(TOP)/progs/util/readtex.c
        ln -s $(TOP)/progs/util/readtex.c .
 
 
+fs-tri: fs-tri.c extfuncs.h
+
+
+extfuncs.h:  $(TOP)/progs/util/extfuncs.h
+       cp $< .
 
 
 # Emacs tags
index 7e7ca588c312db86953d865cdd5ae1692ff2e88f..69931b58182027d73beb79c7351343a8608bb8ac 100644 (file)
@@ -108,7 +108,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 97f878e96b9115a33122ae437bcd42fdae4b7d41..00a75078444eaa4518499d1b786692d9ac60aecd 100644 (file)
@@ -131,7 +131,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 31300efd842bf7536eb21f37eae40bdbbdc93657..b993946320ff521d2f7a45ca80f425ff946392cb 100644 (file)
@@ -134,7 +134,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index fa97f041035f77242d4e0e848facb0702c1b48cb..9e190db7001fe7a556b95b5a2f94d68e25df4aa0 100644 (file)
@@ -138,7 +138,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
diff --git a/progs/trivial/fs-tri.c b/progs/trivial/fs-tri.c
new file mode 100644 (file)
index 0000000..3be4d42
--- /dev/null
@@ -0,0 +1,212 @@
+/* Test fragment shader */
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+#include "extfuncs.h"
+
+
+static GLuint fragShader;
+static GLuint vertShader;
+static GLuint program;
+static GLint win = 0;
+static GLfloat xpos = 0, ypos = 0;
+
+
+static void
+Redisplay(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+   glPushMatrix();
+   glTranslatef(xpos, ypos, 0);
+
+   glBegin(GL_TRIANGLES);
+   glColor3f(1, 0, 0);
+   glVertex2f(-0.9, -0.9);
+   glColor3f(0, 1, 0);
+   glVertex2f( 0.9, -0.9);
+   glColor3f(0, 0, 1);
+   glVertex2f( 0,  0.9);
+   glEnd();
+
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+   glViewport(0, 0, width, height);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(-1, 1, -1, 1, -1, 1);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+
+static void
+CleanUp(void)
+{
+   glDeleteShader_func(fragShader);
+   glDeleteShader_func(vertShader);
+   glDeleteProgram_func(program);
+   glutDestroyWindow(win);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+  (void) x;
+  (void) y;
+
+   switch(key) {
+   case 27:
+      CleanUp();
+      exit(0);
+      break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void
+SpecialKey(int key, int x, int y)
+{
+   const GLfloat step = 0.1;
+
+  (void) x;
+  (void) y;
+
+   switch(key) {
+   case GLUT_KEY_UP:
+      ypos += step;
+      break;
+   case GLUT_KEY_DOWN:
+      ypos -= step;
+      break;
+   case GLUT_KEY_LEFT:
+      xpos -= step;
+      break;
+   case GLUT_KEY_RIGHT:
+      xpos += step;
+      break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void
+LoadAndCompileShader(GLuint shader, const char *text)
+{
+   GLint stat;
+
+   glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
+
+   glCompileShader_func(shader);
+
+   glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
+   if (!stat) {
+      GLchar log[1000];
+      GLsizei len;
+      glGetShaderInfoLog_func(shader, 1000, &len, log);
+      fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log);
+      exit(1);
+   }
+}
+
+
+static void
+CheckLink(GLuint prog)
+{
+   GLint stat;
+   glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
+   if (!stat) {
+      GLchar log[1000];
+      GLsizei len;
+      glGetProgramInfoLog_func(prog, 1000, &len, log);
+      fprintf(stderr, "Linker error:\n%s\n", log);
+   }
+}
+
+
+static void
+Init(void)
+{
+   /* fragment color is a function of fragment position: */
+   static const char *fragShaderText =
+      "void main() {\n"
+      "   gl_FragColor = gl_FragCoord * vec4(0.005); \n"
+      "   //gl_FragColor = gl_Color; \n"
+      "   //gl_FragColor = vec4(1, 0, 0.5, 0); \n"
+      "}\n";
+#if 0
+   static const char *vertShaderText =
+      "varying vec3 normal;\n"
+      "void main() {\n"
+      "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
+      "   normal = gl_NormalMatrix * gl_Normal;\n"
+      "}\n";
+#endif
+   const char *version;
+
+   version = (const char *) glGetString(GL_VERSION);
+   if (version[0] != '2' || version[1] != '.') {
+      printf("This program requires OpenGL 2.x, found %s\n", version);
+      exit(1);
+   }
+
+   GetExtensionFuncs();
+
+   fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
+   LoadAndCompileShader(fragShader, fragShaderText);
+
+#if 0
+   vertShader = glCreateShader_func(GL_VERTEX_SHADER);
+   LoadAndCompileShader(vertShader, vertShaderText);
+#endif
+
+   program = glCreateProgram_func();
+   glAttachShader_func(program, fragShader);
+#if 0
+   glAttachShader_func(program, vertShader);
+#endif
+   glLinkProgram_func(program);
+   CheckLink(program);
+   glUseProgram_func(program);
+
+   assert(glGetError() == 0);
+
+   glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
+
+   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
+}
+
+
+int
+main(int argc, char *argv[])
+{
+   glutInit(&argc, argv);
+   glutInitWindowPosition( 0, 0);
+   glutInitWindowSize(200, 200);
+   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+   win = glutCreateWindow(argv[0]);
+   glutReshapeFunc(Reshape);
+   glutKeyboardFunc(Key);
+   glutSpecialFunc(SpecialKey);
+   glutDisplayFunc(Redisplay);
+   Init();
+   glutMainLoop();
+   return 0;
+}
+
+
index 9acd12acc7b1652dd1ec65c9841af5f34b4d5591..fd79d049c4f0fc1ff74b280fe0d98c08f95023fb 100644 (file)
@@ -122,7 +122,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 8999a8f0b1c6c32a61ae5747d28b56d3f3eee946..038004b4c4aae2d028ef626698bef877f68670fb 100644 (file)
@@ -118,7 +118,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index b24d8452bcdd49fdf319393db6340779c993339a..5c9c1b3b291e2cd2b93da6ecea2f9ab14e1c2401 100644 (file)
@@ -124,7 +124,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index e2e0b85a522eac4ab1db26375cc8220cb598118f..a6ee44fbd0f5600ea5bbde3ad03fcb3f02272233 100644 (file)
@@ -124,7 +124,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index eacee069789853d0acd558b26a949d1d7708e735..cebea5f4812a374f0816a0d6b55aaea5ac6d8342 100644 (file)
@@ -124,7 +124,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 6af91431d0852eee6921e55e81b980c3ba579d46..ecfd28cac7106c9650ec38f49c62ea77f5eba96b 100644 (file)
@@ -124,7 +124,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 58bad91b05aa274c0949dc5c37ce25b9855c02e5..b435a2689a09b5ef34715966f5c8a98544496e30 100644 (file)
@@ -40,7 +40,7 @@ static void Init(void)
    fprintf(stderr, "GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
    fprintf(stderr, "GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
 
-    glClearColor(0.0, 0.0, 1.0, 0.0);
+    glClearColor(0.3, 0.3, 0.3, 0.0);
 }
 
 static void Reshape(int width, int height)
index d8645ee34778e0fe2c3891edbf2981aaeba456eb..211056720fee893ea42ffafeb526dc54560fce22 100644 (file)
@@ -118,7 +118,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 7500c54fc2650e00db08f750770f7cba4adebf59..fab7d1ea0226661267e428073e380a51eea48587 100644 (file)
@@ -118,7 +118,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 32792047c64e7be1843647da6333d4a00eac331c..7fec54e1db93f3440744645c9e21aeba4bdb59fc 100644 (file)
@@ -120,7 +120,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index c5424682b853b4251f0eda6d28426fec7592a194..c50b7cb103422b43f5ec16cbec94c8cef61076ad 100644 (file)
@@ -127,7 +127,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 473ca043f1d2e081073267e1498694b32a5ca077..d1038ecfa15e06119c1feac8789ba5dc54dfd308 100644 (file)
@@ -33,6 +33,8 @@
 
 
 GLenum doubleBuffer;
+static GLboolean smooth = GL_FALSE;
+
 
 static void Init(void)
 {
@@ -58,6 +60,9 @@ static void Key(unsigned char key, int x, int y)
 {
 
     switch (key) {
+     case 's':
+        smooth = !smooth;
+        break;
       case 27:
        exit(1);
       default:
@@ -73,6 +78,16 @@ static void Draw(void)
 
    glPointSize(8.0);
 
+   if (smooth) {
+      glEnable(GL_POINT_SMOOTH);
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+   }
+   else {
+      glDisable(GL_POINT_SMOOTH);
+      glDisable(GL_BLEND);
+   }
+
    glBegin(GL_POINTS);
    glColor3f(1,0,0); 
    glVertex3f( 0.9, -0.9, -30.0);
@@ -122,7 +137,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 87465bfb2c1b8c835f78aa2801bbb46e9aae9823..8dabfb6ca64eb6809577aee17332164aec805ffc 100644 (file)
@@ -120,7 +120,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 747b24dc0ce32ca13a2bf03b3643d355ab59b6ab..a847d6828a7d59724a5e137d640c3c79e79dd80d 100644 (file)
@@ -122,7 +122,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index e0ae463b083a69f27a7ad9fccac22940a7fc6ed0..ae092a830ab2e61289c230274a4cd696da25ae76 100644 (file)
@@ -121,7 +121,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index bdb9e27aa91101ace21b4ed71970ffe4e60a14f6..2f254de48158fa881811bc661bcf6a187df4effb 100644 (file)
@@ -120,7 +120,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 019ef0c479a57efda5377e3ed547d2371c7c923f..3e0f3d949483df11f8199901064b27a69bea00e8 100644 (file)
@@ -120,7 +120,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 7e12e58a196b0355fcc7fb5655b4171171e57ce0..e76eb29f890b4729ec252e8706f87946738c2885 100644 (file)
@@ -120,7 +120,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 9f3a45caec3608b98a01f85e7071adda5f60d7ea..504fef3dc593ff770a0144c27f499804f9d924e4 100644 (file)
@@ -120,7 +120,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index b14b0f1d879f425ce42bc213a5455c604efee6cf..83047408573f19320a4ff5f3843426b4876b64f4 100644 (file)
@@ -125,7 +125,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index d6e9f02120653e000aa68b091a6350794c494509..bd8be7c43e3088f1696dd6dc44464b512261f838 100644 (file)
@@ -130,7 +130,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 861d3461c041722ec620f42e750bf16f481d73de..90943d908ff377f7c765cfaa8dffa032f22fd05b 100644 (file)
 #include <stdlib.h>
 #include <GL/glut.h>
 
-
-#define CI_OFFSET_1 16
-#define CI_OFFSET_2 32
-
-
 GLenum doubleBuffer;
 
 static void Init(void)
@@ -45,7 +40,6 @@ static void Init(void)
 
 static void Reshape(int width, int height)
 {
-
     glViewport(0, 0, (GLint)width, (GLint)height);
 
     glMatrixMode(GL_PROJECTION);
@@ -56,7 +50,6 @@ static void Reshape(int width, int height)
 
 static void Key(unsigned char key, int x, int y)
 {
-
     switch (key) {
       case 27:
        exit(1);
@@ -75,7 +68,6 @@ static void quad( float half )
    glVertex3f(-half/9.0,  half/9.0, -25.0 - half);
    glVertex3f(-half/9.0, -half/9.0, -25.0 - half);
    glEnd();
-
 }
 
 static void Draw(void)
@@ -83,27 +75,24 @@ static void Draw(void)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glEnable(GL_DEPTH_TEST);
 
-
-
+   /* red: offset back */
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(1, 0);
-
    glColor3f(1,0,0); 
    quad(9);
 
+   /* green: no offset */
    glDisable(GL_POLYGON_OFFSET_FILL); 
    glColor3f(0,1,0); 
    quad(6);
 
-
+   /* black: offset zero, should not be visible because of z test */
    glEnable(GL_POLYGON_OFFSET_FILL); 
    glPolygonOffset(0, 0); 
-
-   /* Black - should not be visible
-    */
    glColor3f(0,0,0); 
    quad(6);
 
+   /* blue: offset forward */
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(-1, 0);
    glColor3f(0,0,1); 
@@ -149,7 +138,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB | GLUT_DEPTH;
+    type = GLUT_RGB | GLUT_ALPHA | GLUT_DEPTH;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
@@ -163,5 +152,5 @@ int main(int argc, char **argv)
     glutKeyboardFunc(Key);
     glutDisplayFunc(Draw);
     glutMainLoop();
-       return 0;
+    return 0;
 }
index 1cecf3c1cefa9a1640ee49034dd5162410a5f259..32b2129727bf00d896d30dad32d39ae8d44da133 100644 (file)
@@ -149,7 +149,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB | GLUT_DEPTH;
+    type = GLUT_RGB | GLUT_ALPHA | GLUT_DEPTH;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 5c41be308ee17d417fd3953096f8e475880f71a5..d5db21469e61dacee1f759df01cc4dae762c9db6 100644 (file)
 #include <stdlib.h>
 #include <GL/glut.h>
 
-
-#define CI_OFFSET_1 16
-#define CI_OFFSET_2 32
-
-
 GLenum doubleBuffer;
 
 static void Init(void)
@@ -45,7 +40,6 @@ static void Init(void)
 
 static void Reshape(int width, int height)
 {
-
     glViewport(0, 0, (GLint)width, (GLint)height);
 
     glMatrixMode(GL_PROJECTION);
@@ -56,7 +50,6 @@ static void Reshape(int width, int height)
 
 static void Key(unsigned char key, int x, int y)
 {
-
     switch (key) {
       case 27:
        exit(1);
@@ -75,7 +68,6 @@ static void quad( float half )
    glVertex3f(-half/9.0,  half/9.0, -25.0 - half);
    glVertex3f(-half/9.0, -half/9.0, -25.0 - half);
    glEnd();
-
 }
 
 static void Draw(void)
@@ -83,27 +75,26 @@ static void Draw(void)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glEnable(GL_DEPTH_TEST);
 
-
-
+   /* red: offset back */
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(0, 4);
-
    glColor3f(1,0,0); 
    quad(9);
 
+   /* black: no offset */
    glDisable(GL_POLYGON_OFFSET_FILL); 
    glColor3f(0,0,0); 
    quad(6);
 
+   /* green: offset 0 (this should obscure the black quad) */
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(0, 0);
-
    glDepthFunc( GL_EQUAL );
    glColor3f(0,1,0); 
    quad(6);
-   glDepthFunc( GL_LESS );
-
 
+   /* blue: offset forward */
+   glDepthFunc( GL_LESS );
    glPolygonOffset(0, -4);
    glColor3f(0,0,1); 
    quad(3);
@@ -148,7 +139,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB | GLUT_DEPTH;
+    type = GLUT_RGB | GLUT_ALPHA | GLUT_DEPTH;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
@@ -162,5 +153,5 @@ int main(int argc, char **argv)
     glutKeyboardFunc(Key);
     glutDisplayFunc(Draw);
     glutMainLoop();
-       return 0;
+    return 0;
 }
index 0b2dcc08a5f0fa0a6286ed13e3ffdf340381a03c..fd02d9d6adc3427e1c1f0e5566ae9641ad5f875c 100644 (file)
@@ -159,7 +159,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 9d63d2dfb95016e6bd12d0f352660b6644a26eb6..9d0087ce08d12a6d21dcf71cdf008a32555ea381 100644 (file)
@@ -121,7 +121,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 1ca82cd9f8bbea4f3d3d419cfbd1bd60200aa115..307a9e0720999cf1daae66d818f5f503a9fc7d7d 100644 (file)
@@ -138,7 +138,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 061a0e409e4e2a20e89bdaffaa3c3b19ba6b5b8c..d02135f702a603ae3ba81027654aeb1d518579e1 100644 (file)
@@ -132,7 +132,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 342463f1a24ac8d64faf1c3e0eef920366502853..ff8644be09eecbb212fb8b9f8847b836f6b88104 100644 (file)
@@ -126,7 +126,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 284d15fd3c9878db7795c5f133750ab3ad06e164..58c451c976935966ca4198db56c1a256e8c03df3 100644 (file)
@@ -132,7 +132,7 @@ void keyboard(unsigned char key, int x, int y)
 int main(int argc, char** argv)
 {
    glutInit(&argc, argv);
-   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_ALPHA);
    glutInitWindowSize (200, 200);
    glutCreateWindow (argv[0]);
    init();
index bf48533adcced0e7405beb7f58964eab1c18b7e2..f30445cdba1c751da2c878f9946363c407199f6d 100644 (file)
 #include <GL/glut.h>
 
 
-#define CI_OFFSET_1 16
-#define CI_OFFSET_2 32
+static GLenum doubleBuffer;
+static GLfloat Xpos = 0, Ypos = 0;
 
 
-GLenum doubleBuffer;
-
 static void Init(void)
 {
    fprintf(stderr, "GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
    fprintf(stderr, "GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
    fprintf(stderr, "GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
-
-    glClearColor(0.0, 0.0, 1.0, 0.0);
+   glClearColor(0.0, 0.0, 1.0, 0.0);
 }
 
 static void Reshape(int width, int height)
 {
-
     glViewport(0, 0, (GLint)width, (GLint)height);
-
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
@@ -56,21 +51,45 @@ static void Reshape(int width, int height)
 
 static void Key(unsigned char key, int x, int y)
 {
-
     switch (key) {
       case 27:
        exit(1);
       default:
        return;
     }
-
     glutPostRedisplay();
 }
 
+static void
+SpecialKey(int key, int x, int y)
+{
+   const GLfloat step = 0.25;
+   (void) x;
+   (void) y;
+   switch (key) {
+      case GLUT_KEY_UP:
+         Ypos += step;
+         break;
+      case GLUT_KEY_DOWN:
+         Ypos -= step;
+         break;
+      case GLUT_KEY_LEFT:
+         Xpos -= step;
+         break;
+      case GLUT_KEY_RIGHT:
+         Xpos += step;
+         break;
+   }
+   glutPostRedisplay();
+}
+
 static void Draw(void)
 {
    glClear(GL_COLOR_BUFFER_BIT); 
 
+   glPushMatrix();
+   glTranslatef(Xpos, Ypos, 0);
+
    glBegin(GL_TRIANGLES);
    glColor3f(0,0,.7); 
    glVertex3f( 0.9, -0.9, -30.0);
@@ -80,12 +99,13 @@ static void Draw(void)
    glVertex3f(-1.9,  0.0, -30.0);
    glEnd();
 
+   glPopMatrix();
+
    glFlush();
 
    if (doubleBuffer) {
       glutSwapBuffers();
    }
-
 }
 
 static GLenum Args(int argc, char **argv)
@@ -131,7 +151,8 @@ int main(int argc, char **argv)
 
     glutReshapeFunc(Reshape);
     glutKeyboardFunc(Key);
+    glutSpecialFunc(SpecialKey);
     glutDisplayFunc(Draw);
     glutMainLoop();
-       return 0;
+    return 0;
 }
index 20aeaf1d7cddfb8f8ff838a4950744778a3b28ba..2eead8411558e15bcaeaf1318f4fc88adec79fd5 100644 (file)
 #include <stdlib.h>
 #include <GL/glut.h>
 
+static GLenum doubleBuffer;
+static GLint cullmode = 0;
+static GLenum front = GL_CCW; /* GL default */
 
-#define CI_OFFSET_1 16
-#define CI_OFFSET_2 32
-
-
-GLenum doubleBuffer;
+static void cull(void)
+{
+   cullmode = (cullmode + 1) % 4;
+   if (cullmode == 0) {
+      glCullFace(GL_FRONT);
+      glEnable(GL_CULL_FACE);
+      printf("cull GL_FRONT\n");
+   }
+   else if (cullmode == 1) {
+      glCullFace(GL_BACK);
+      glEnable(GL_CULL_FACE);
+      printf("cull GL_BACK\n");
+   }
+   else if (cullmode == 2) {
+      glCullFace(GL_FRONT_AND_BACK);
+      glEnable(GL_CULL_FACE);
+      printf("cull GL_FRONT_AND_BACK\n");
+   }
+   else {
+      glDisable(GL_CULL_FACE);
+      printf("cull none\n");
+   }
+}
 
 static void Init(void)
 {
    fprintf(stderr, "GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
    fprintf(stderr, "GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
    fprintf(stderr, "GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
-
-    glClearColor(0.0, 0.0, 1.0, 0.0);
+   glClearColor(0.0, 0.0, 1.0, 0.0);
+   cull();
 }
 
 static void Reshape(int width, int height)
 {
-
     glViewport(0, 0, (GLint)width, (GLint)height);
 
     glMatrixMode(GL_PROJECTION);
@@ -56,15 +76,21 @@ static void Reshape(int width, int height)
 
 static void Key(unsigned char key, int x, int y)
 {
-
-    switch (key) {
-      case 27:
-       exit(1);
-      default:
-       return;
-    }
-
-    glutPostRedisplay();
+   switch (key) {
+   case 27:
+      exit(1);
+   case 'c':
+      cull();
+      break;
+   case 'f':
+      front = ((front == GL_CCW) ? GL_CW : GL_CCW);
+      glFrontFace(front);
+      printf("front face = %s\n", front == GL_CCW ? "GL_CCW" : "GL_CW");
+      break;
+   default:
+      return;
+   }
+   glutPostRedisplay();
 }
 
 static void Draw(void)
@@ -72,12 +98,22 @@ static void Draw(void)
    glClear(GL_COLOR_BUFFER_BIT); 
 
    glBegin(GL_TRIANGLES);
-   glColor3f(0,0,1); 
-   glVertex3f( -1.5, 0.5, -30.0);
-   glColor3f(1,0,0); 
-   glVertex3f( 0,  2.0, -30.0);
-   glColor3f(0,1,0); 
-   glVertex3f(-1.5, 2.0, -30.0);
+   /* CCW / front-facing */
+   glColor3f(0,0,.7); 
+   glVertex3f(-0.1, -0.9, -30.0);
+   glColor3f(.8,0,0); 
+   glVertex3f(-0.1,  0.9, -30.0);
+   glColor3f(0,.9,0); 
+   glVertex3f(-0.9,  0.0, -30.0);
+
+   /* CW / back-facing */
+   glColor3f(0,0,.7); 
+   glVertex3f( 0.1, -0.9, -30.0);
+   glColor3f(.8,0,0); 
+   glVertex3f( 0.1,  0.9, -30.0);
+   glColor3f(0,.9,0); 
+   glVertex3f( 0.9,  0.0, -30.0);
+
    glEnd();
 
    glFlush();
@@ -118,7 +154,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
@@ -132,5 +168,5 @@ int main(int argc, char **argv)
     glutKeyboardFunc(Key);
     glutDisplayFunc(Draw);
     glutMainLoop();
-       return 0;
+    return 0;
 }
index e0ab285eff4f6c13a4724aa1d2ece2423f38c6cf..c21c4714adf15067dda859cb7484295bb85f3583 100644 (file)
@@ -132,7 +132,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index bdc0eaa253a8b0861e85fd9f9dbbdbb05a55903e..41899c2eb4f869226a6ac78435fd86336db48e81 100644 (file)
 #include <stdlib.h>
 #include <GL/glut.h>
 
-
-#define CI_OFFSET_1 16
-#define CI_OFFSET_2 32
-
-
-GLenum doubleBuffer;
+static GLenum doubleBuffer;
+static GLenum frontface = GL_CCW;
 
 static void Init(void)
 {
    fprintf(stderr, "GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
    fprintf(stderr, "GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
    fprintf(stderr, "GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
-
-    glClearColor(0.0, 0.0, 1.0, 0.0);
 }
 
 static void Reshape(int width, int height)
 {
-
     glViewport(0, 0, (GLint)width, (GLint)height);
 
     glMatrixMode(GL_PROJECTION);
@@ -56,13 +49,16 @@ static void Reshape(int width, int height)
 
 static void Key(unsigned char key, int x, int y)
 {
-
-    switch (key) {
-      case 27:
-       exit(1);
-      default:
-       return;
-    }
+   switch (key) {
+   case 'f':
+      frontface = (frontface == GL_CCW) ? GL_CW : GL_CCW;
+      glFrontFace(frontface);
+      break;
+   case 27:
+      exit(1);
+   default:
+      return;
+   }
 
     glutPostRedisplay();
 }
@@ -75,7 +71,7 @@ static void Draw(void)
 
    glBegin(GL_TRIANGLES);
    glEdgeFlag(1);
-   glColor3f(0,0,.7); 
+   glColor3f(0.3,0.3,.9); 
    glVertex3f( 0.9, -0.9, -0.0);
    glEdgeFlag(0);
    glColor3f(.8,0,0); 
@@ -123,7 +119,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
@@ -137,5 +133,5 @@ int main(int argc, char **argv)
     glutKeyboardFunc(Key);
     glutDisplayFunc(Draw);
     glutMainLoop();
-       return 0;
+    return 0;
 }
index fafa64914d4e3893cf46cd9b3235431ed259b152..155b0c4f8d40fb85ebc3a28dfc2f6043ebb43824 100644 (file)
@@ -119,7 +119,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index fb2cdbd7bba80c2eb21a306718052fb2b83edfc6..0583a2a99a1160cb0bd8e986fe07dc16b907028f 100644 (file)
@@ -119,7 +119,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 6a9d1d1bf6d4f17feeacd89c54be5387b81f3b5d..613803fd1b1920eaf5c13b5678ef3997d1dc8ba3 100644 (file)
@@ -152,7 +152,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index d486af23655f28fb2024bcdd0e71c6168c5ea7f2..df161df3fb82928140a2be94690c7de5448c9d50 100644 (file)
@@ -119,7 +119,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index e41903a3d50f6eaf4c354463982343dc7cc63286..f70c1cd9d4dac0a89cd90300b061999b764811e9 100644 (file)
@@ -132,7 +132,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index dc93a8f1abf9da589c83956f5db4ca59e1dcc5f0..9201f9d433cefc5c69cac6bba1813450e3a0f833 100644 (file)
@@ -123,7 +123,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 73961bc93a61e5433150de55d33a7e5e23e3f636..1e44823db5a7433a96a988f70e6f8550a24bb9b6 100644 (file)
@@ -120,7 +120,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index cde9662ace92e7be56992f52673f6a37994a68af..ccf631dff80c5f1a564f1f11a148043d93c7ef6e 100644 (file)
@@ -122,7 +122,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
diff --git a/progs/trivial/tri-z.c b/progs/trivial/tri-z.c
new file mode 100644 (file)
index 0000000..ae25900
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+#include <GL/glut.h>
+#include <stdlib.h>
+
+static int leftFirst = GL_TRUE;
+
+static void init(void)
+{
+   glEnable(GL_DEPTH_TEST);
+   glClearColor (1.0, 0.0, 0.0, 0.0);
+}
+
+static void drawLeftTriangle(void)
+{
+   /* draw yellow triangle on LHS of screen */
+   glBegin (GL_TRIANGLES);
+      glColor4f(1.0, 1.0, 0.0, 0.75);
+      glVertex3f(0.1, 0.9, -1.0); 
+      glVertex3f(0.1, 0.1, -1.0); 
+      glVertex3f(0.8, 0.5,  1.0); 
+   glEnd();
+}
+
+static void drawRightTriangle(void)
+{
+   /* draw cyan triangle on RHS of screen */
+   glBegin (GL_TRIANGLES);
+      glColor4f(0.0, 1.0, 1.0, 0.75);
+      glVertex3f(0.9, 0.9, 0.0); 
+      glVertex3f(0.2, 0.5, 0.0); 
+      glVertex3f(0.9, 0.1, 0.0); 
+   glEnd();
+}
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+   if (leftFirst) {
+      drawLeftTriangle();
+      drawRightTriangle();
+   }
+   else {
+      drawRightTriangle();
+      drawLeftTriangle();
+   }
+
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h) 
+      gluOrtho2D (0.0, 1.0, 0.0, 1.0*(GLfloat)h/(GLfloat)w);
+   else 
+      gluOrtho2D (0.0, 1.0*(GLfloat)w/(GLfloat)h, 0.0, 1.0);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 't':
+      case 'T':
+         leftFirst = !leftFirst;
+         glutPostRedisplay();  
+         break;
+      case 27:  /*  Escape key  */
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize (200, 200);
+   glutCreateWindow (argv[0]);
+   init();
+   glutReshapeFunc (reshape);
+   glutKeyboardFunc (keyboard);
+   glutDisplayFunc (display);
+   glutMainLoop();
+   return 0;
+}
index 58a650b559fef8cd7343222099fa0d8b5f9d9f26..51395f0a418a641d45fec863e0438e6f32f088a7 100644 (file)
@@ -32,7 +32,7 @@
 #define CI_OFFSET_2 32
 
 
-GLenum doubleBuffer;
+GLenum doubleBuffer = 1;
 
 static void Init(void)
 {
@@ -40,7 +40,7 @@ static void Init(void)
    fprintf(stderr, "GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
    fprintf(stderr, "GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
 
-    glClearColor(0.0, 0.0, 1.0, 0.0);
+    glClearColor(0.3, 0.1, 0.3, 0.0);
 }
 
 static void Reshape(int width, int height)
@@ -91,8 +91,6 @@ static GLenum Args(int argc, char **argv)
 {
     GLint i;
 
-    doubleBuffer = GL_FALSE;
-
     for (i = 1; i < argc; i++) {
         if (strcmp(argv[i], "-sb") == 0) {
            doubleBuffer = GL_FALSE;
@@ -118,7 +116,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index fa82a737112ce73393c15c8ee2a5e8a6b0b3e49c..51ea4f23251818eab61a1eef94e2cdd20c6b7e67 100644 (file)
@@ -120,7 +120,7 @@ int main(int argc, char **argv)
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB;
+    type = GLUT_RGB | GLUT_ALPHA;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
index 3e92e68daa7a5a6556df274851b771ec4b759c9f..0ad9147aea6d9be65775353a652189cf4198752e 100644 (file)
@@ -71,12 +71,12 @@ typedef Vertex Quad[4];
 
 /* data to define the six faces of a unit cube */
 Quad quads[MAXQUAD] = {
-   { {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0} },
-   { {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1} },
-   { {0,0,0}, {1,0,0}, {1,0,1}, {0,0,1} },
-   { {0,1,0}, {1,1,0}, {1,1,1}, {0,1,1} },
-   { {0,0,0}, {0,0,1}, {0,1,1}, {0,1,0} },
-   { {1,0,0}, {1,0,1}, {1,1,1}, {1,1,0} }
+   { {0,0,0}, {0,0,1}, {0,1,1}, {0,1,0} }, /* x = 0 */
+   { {0,0,0}, {1,0,0}, {1,0,1}, {0,0,1} }, /* y = 0 */
+   { {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0} }, /* z = 0 */
+   { {1,0,0}, {1,0,1}, {1,1,1}, {1,1,0} }, /* x = 1 */
+   { {0,1,0}, {1,1,0}, {1,1,1}, {0,1,1} }, /* y = 1 */
+   { {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1} }  /* z = 1 */
 };
 
 #define WIREFRAME      0
@@ -86,7 +86,7 @@ static void error(const char* prog, const char* msg);
 static void cubes(int mx, int my, int mode);
 static void fill(Quad quad);
 static void outline(Quad quad);
-static void draw_hidden(Quad quad, int mode);
+static void draw_hidden(Quad quad, int mode, int face);
 static void process_input(Display *dpy, Window win);
 static int query_extension(char* extName);
 
@@ -101,6 +101,7 @@ int main(int argc, char** argv) {
     XSetWindowAttributes swa;
     Window win;
     GLXContext cx;
+    GLint z;
 
     dpy = XOpenDisplay(0);
     if (!dpy) error(argv[0], "can't open display");
@@ -134,13 +135,16 @@ int main(int argc, char** argv) {
 
     /* set up viewing parameters */
     glMatrixMode(GL_PROJECTION);
-    gluPerspective(20, 1, 0.1, 20);
+    gluPerspective(20, 1, 10, 20);
     glMatrixMode(GL_MODELVIEW);
     glTranslatef(0, 0, -15);
 
     /* set other relevant state information */
     glEnable(GL_DEPTH_TEST);
 
+    glGetIntegerv(GL_DEPTH_BITS, &z);
+    printf("GL_DEPTH_BITS = %d\n", z);
+
 #ifdef GL_EXT_polygon_offset
     printf("using 1.0 offset extension\n");
     glPolygonOffsetEXT( 1.0, 0.00001 );
@@ -160,6 +164,7 @@ int main(int argc, char** argv) {
 
 static void
 draw_scene(int mx, int my) {
+   glClearColor(0.25, 0.25, 0.25, 0);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
     glPushMatrix();
@@ -206,7 +211,7 @@ cubes(int mx, int my, int mode) {
                glTranslatef(x, y, z);
                glScalef(0.8, 0.8, 0.8);
                for (i = 0; i < MAXQUAD; i++)
-                   draw_hidden(quads[i], mode);
+                    draw_hidden(quads[i], mode, i);
                glPopMatrix();
            }
        }
@@ -236,13 +241,18 @@ outline(Quad quad) {
 }
 
 static void
-draw_hidden(Quad quad, int mode) {
+draw_hidden(Quad quad, int mode, int face) {
+    static const GLfloat colors[3][3] = {
+        {0.5, 0.5, 0.0},
+        {0.8, 0.5, 0.0},
+        {0.0, 0.5, 0.8}
+    };
     if (mode == HIDDEN_LINE) {
-       glColor3f(0, 0, 0);
+        glColor3fv(colors[face % 3]);
        fill(quad);
     }
 
-    /* draw the outline using white, optionally fill the interior with black */
+    /* draw the outline using white */
     glColor3f(1, 1, 1);
     outline(quad);
 }
index efdfdfa452227f8086418263321db281ce28abba..7db0017b33ec283a5643308b73f434145f09f7ed 100644 (file)
@@ -93,7 +93,7 @@ MakePbuffer( Display *dpy, int screen, int width, int height )
          None
       },
       {
-         /* Single bufferd, without depth buffer */
+         /* Single buffered, without depth buffer */
          GLX_RENDER_TYPE, GLX_RGBA_BIT,
          GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
          GLX_RED_SIZE, 1,
@@ -105,7 +105,7 @@ MakePbuffer( Display *dpy, int screen, int width, int height )
          None
       },
       {
-         /* Double bufferd, without depth buffer */
+         /* Double buffered, without depth buffer */
          GLX_RENDER_TYPE, GLX_RGBA_BIT,
          GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
          GLX_RED_SIZE, 1,
@@ -130,9 +130,8 @@ MakePbuffer( Display *dpy, int screen, int width, int height )
       /* Get list of possible frame buffer configurations */
       fbConfigs = ChooseFBConfig(dpy, screen, fbAttribs[attempt], &nConfigs);
       if (nConfigs==0 || !fbConfigs) {
-         printf("Error: glXChooseFBConfig failed\n");
-         XCloseDisplay(dpy);
-         return 0;
+         printf("Note: glXChooseFBConfig(%s) failed\n", fbString[attempt]);
+         continue;
       }
 
 #if 0 /*DEBUG*/
diff --git a/src/glu/sgi/Makefile.mgw b/src/glu/sgi/Makefile.mgw
new file mode 100644 (file)
index 0000000..43b421e
--- /dev/null
@@ -0,0 +1,229 @@
+# 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.
+
+# MinGW core makefile v1.4 for Mesa
+#
+#  Copyright (C) 2002 - Daniel Borca
+#  Email : dborca@users.sourceforge.net
+#  Web   : http://www.geocities.com/dborca
+
+# MinGW core-glu makefile updated for Mesa 7.0
+#
+#  Updated : by Heromyth, on 2007-7-21
+#  Email   : zxpmyth@yahoo.com.cn
+#  Bugs    : 1) All the default settings work fine. But the setting X86=1 can't work. 
+#            The others havn't been tested yet.
+#            2) The generated DLLs are *not* compatible with the ones built
+#            with the other compilers like VC8, especially for GLUT. 
+#            3) Although more tests are needed, it can be used individually!
+
+#
+#  Available options:
+#
+#    Environment variables:
+#      CFLAGS
+#
+#      GLIDE           path to Glide3 SDK; used with FX.
+#                      default = $(TOP)/glide3
+#      FX=1            build for 3dfx Glide3. Note that this disables
+#                      compilation of most WMesa code and requires fxMesa.
+#                      As a consequence, you'll need the Win32 Glide3
+#                      library to build any application.
+#                      default = no
+#      ICD=1           build the installable client driver interface
+#                      (windows opengl driver interface)
+#                      default = no
+#      X86=1           optimize for x86 (if possible, use MMX, SSE, 3DNow).
+#                      default = no
+#
+#    Targets:
+#      all:            build GL
+#      clean:          remove object files
+#
+
+
+
+.PHONY: all clean
+.INTERMEDIATE: x86/gen_matypes.exe
+.SUFFIXES: .rc .res
+
+# Set this to the prefix of your build tools, i.e. mingw32-
+TOOLS_PREFIX = mingw32-
+
+TOP = ../../..
+
+LIBDIR = $(TOP)/lib
+
+GLU_DLL = glu32.dll
+GLU_IMP = libglu32.a
+GLU_DEF = glu.def
+
+include $(TOP)/configs/config.mgw
+GL_USING_STDCALL ?= 1
+
+LDLIBS = -L$(LIBDIR) -lopengl32
+LDFLAGS = -Wl,--out-implib=$(LIBDIR)/$(GLU_IMP) -Wl,--output-def=$(LIBDIR)/$(GLU_DEF)
+
+CFLAGS += -DBUILD_GLU32 -D_DLL
+
+ifeq ($(GL_USING_STDCALL),1)
+  LDFLAGS += -Wl,--add-stdcall-alias
+else
+  CFLAGS += -DGL_NO_STDCALL
+endif
+
+CC = gcc
+CFLAGS += -DNDEBUG -DLIBRARYBUILD -I$(TOP)/include -Iinclude
+CXX = g++
+CXXFLAGS = $(CFLAGS) -Ilibnurbs/internals -Ilibnurbs/interface -Ilibnurbs/nurbtess
+
+AR = ar
+ARFLAGS = crus
+
+UNLINK = del $(subst /,\,$(1))
+ifneq ($(wildcard $(addsuffix /rm.exe,$(subst ;, ,$(PATH)))),)
+UNLINK = $(RM) $(1)
+endif
+ifneq ($(wildcard $(addsuffix /rm,$(subst :, ,$(PATH)))),)
+UNLINK = $(RM) $(1)
+endif
+
+C_SOURCES = \
+       libutil/error.c \
+       libutil/glue.c \
+       libutil/mipmap.c \
+       libutil/project.c \
+       libutil/quad.c \
+       libutil/registry.c \
+       libtess/dict.c \
+       libtess/geom.c \
+       libtess/memalloc.c \
+       libtess/mesh.c \
+       libtess/normal.c \
+       libtess/priorityq.c \
+       libtess/render.c \
+       libtess/sweep.c \
+       libtess/tess.c \
+       libtess/tessmono.c
+
+CC_SOURCES = \
+       libnurbs/interface/bezierEval.cc \
+       libnurbs/interface/bezierPatch.cc \
+       libnurbs/interface/bezierPatchMesh.cc \
+       libnurbs/interface/glcurveval.cc \
+       libnurbs/interface/glinterface.cc \
+       libnurbs/interface/glrenderer.cc \
+       libnurbs/interface/glsurfeval.cc \
+       libnurbs/interface/incurveeval.cc \
+       libnurbs/interface/insurfeval.cc \
+       libnurbs/internals/arc.cc \
+       libnurbs/internals/arcsorter.cc \
+       libnurbs/internals/arctess.cc \
+       libnurbs/internals/backend.cc \
+       libnurbs/internals/basiccrveval.cc \
+       libnurbs/internals/basicsurfeval.cc \
+       libnurbs/internals/bin.cc \
+       libnurbs/internals/bufpool.cc \
+       libnurbs/internals/cachingeval.cc \
+       libnurbs/internals/ccw.cc \
+       libnurbs/internals/coveandtiler.cc \
+       libnurbs/internals/curve.cc \
+       libnurbs/internals/curvelist.cc \
+       libnurbs/internals/curvesub.cc \
+       libnurbs/internals/dataTransform.cc \
+       libnurbs/internals/displaylist.cc \
+       libnurbs/internals/flist.cc \
+       libnurbs/internals/flistsorter.cc \
+       libnurbs/internals/hull.cc \
+       libnurbs/internals/intersect.cc \
+       libnurbs/internals/knotvector.cc \
+       libnurbs/internals/mapdesc.cc \
+       libnurbs/internals/mapdescv.cc \
+       libnurbs/internals/maplist.cc \
+       libnurbs/internals/mesher.cc \
+       libnurbs/internals/monoTriangulationBackend.cc \
+       libnurbs/internals/monotonizer.cc \
+       libnurbs/internals/mycode.cc \
+       libnurbs/internals/nurbsinterfac.cc \
+       libnurbs/internals/nurbstess.cc \
+       libnurbs/internals/patch.cc \
+       libnurbs/internals/patchlist.cc \
+       libnurbs/internals/quilt.cc \
+       libnurbs/internals/reader.cc \
+       libnurbs/internals/renderhints.cc \
+       libnurbs/internals/slicer.cc \
+       libnurbs/internals/sorter.cc \
+       libnurbs/internals/splitarcs.cc \
+       libnurbs/internals/subdivider.cc \
+       libnurbs/internals/tobezier.cc \
+       libnurbs/internals/trimline.cc \
+       libnurbs/internals/trimregion.cc \
+       libnurbs/internals/trimvertpool.cc \
+       libnurbs/internals/uarray.cc \
+       libnurbs/internals/varray.cc \
+       libnurbs/nurbtess/directedLine.cc \
+       libnurbs/nurbtess/gridWrap.cc \
+       libnurbs/nurbtess/monoChain.cc \
+       libnurbs/nurbtess/monoPolyPart.cc \
+       libnurbs/nurbtess/monoTriangulation.cc \
+       libnurbs/nurbtess/partitionX.cc \
+       libnurbs/nurbtess/partitionY.cc \
+       libnurbs/nurbtess/polyDBG.cc \
+       libnurbs/nurbtess/polyUtil.cc \
+       libnurbs/nurbtess/primitiveStream.cc \
+       libnurbs/nurbtess/quicksort.cc \
+       libnurbs/nurbtess/rectBlock.cc \
+       libnurbs/nurbtess/sampleComp.cc \
+       libnurbs/nurbtess/sampleCompBot.cc \
+       libnurbs/nurbtess/sampleCompRight.cc \
+       libnurbs/nurbtess/sampleCompTop.cc \
+       libnurbs/nurbtess/sampleMonoPoly.cc \
+       libnurbs/nurbtess/sampledLine.cc \
+       libnurbs/nurbtess/searchTree.cc
+
+SOURCES = $(C_SOURCES) $(CC_SOURCES)
+
+OBJECTS = $(addsuffix .o,$(basename $(SOURCES)))
+
+.c.o:
+       $(CC) -o $@ $(CFLAGS) -c $<
+.cc.o:
+       $(CXX) -o $@ $(CXXFLAGS) -c $<
+
+
+all: $(LIBDIR) $(LIBDIR)/$(GLU_DLL) $(LIBDIR)/$(GLU_IMP)
+
+$(LIBDIR):
+       mkdir -p $(LIBDIR)
+
+$(LIBDIR)/$(GLU_DLL) $(LIBDIR)/$(GLU_IMP): $(OBJECTS)
+       g++ -shared -fPIC -o $(LIBDIR)/$(GLU_DLL) $(LDFLAGS) \
+    $^ $(LDLIBS)
+
+
+
+clean:
+       -$(call UNLINK,libutil/*.o)
+       -$(call UNLINK,libtess/*.o)
+       -$(call UNLINK,libnurbs/interface/*.o)
+       -$(call UNLINK,libnurbs/internals/*.o)
+       -$(call UNLINK,libnurbs/nurbtess/*.o)
index 4b44f6e847e242666174fe8cae06cf1964332661..a09a74d04c3de6d9b870959f0540f2f5b0eb204c 100644 (file)
@@ -93,7 +93,7 @@ public:
        output_triangles = flag;
       }
 #ifdef _WIN32
-    void               putCallBack(GLenum which, void (APIENTRY *fn)() );
+    void               putCallBack(GLenum which, void (GLAPIENTRY *fn)() );
 #else
     void               putCallBack(GLenum which, _GLUfuncptr fn );
 #endif
index a36b304508c456bc08c8ea3eafb10832bd836672..b5bfab1e2811a449d12ea664dba66dda0c83b737 100644 (file)
@@ -1184,8 +1184,11 @@ return;
 
 }
 
-void
-OpenGLSurfaceEvaluator::putCallBack(GLenum which, _GLUfuncptr fn )
+#ifdef _WIN32
+void OpenGLSurfaceEvaluator::putCallBack(GLenum which, void (GLAPIENTRY *fn)() )
+#else
+void OpenGLSurfaceEvaluator::putCallBack(GLenum which, _GLUfuncptr fn )
+#endif
 {
   switch(which)
     {
index c34a58cb9b91df86be77f8f13b07cdd8dabb723e..b7a88069f5ad9038e6e3eed6cd26b24860fab4b7 100644 (file)
@@ -145,7 +145,7 @@ public:
     void               newtmeshvert( long, long );
 
 #ifdef _WIN32
-    void               putCallBack(GLenum which, void (APIENTRY *fn)() );
+    void               putCallBack(GLenum which, void (GLAPIENTRY *fn)() );
 #else
     void               putCallBack(GLenum which, _GLUfuncptr fn );
 #endif
diff --git a/src/glut/glx/Makefile.mgw b/src/glut/glx/Makefile.mgw
new file mode 100644 (file)
index 0000000..ae4eb6a
--- /dev/null
@@ -0,0 +1,198 @@
+# 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.
+
+# MinGW core makefile v1.4 for Mesa
+#
+#  Copyright (C) 2002 - Daniel Borca
+#  Email : dborca@users.sourceforge.net
+#  Web   : http://www.geocities.com/dborca
+
+# MinGW core-glut makefile updated for Mesa 7.0
+#
+#  Updated : by Heromyth, on 2007-7-21
+#  Email   : zxpmyth@yahoo.com.cn
+#  Bugs    : 1) All the default settings work fine. But the setting X86=1 can't work. 
+#            The others havn't been tested yet.
+#            2) The generated DLLs are *not* compatible with the ones built
+#            with the other compilers like VC8, especially for GLUT. 
+#            3) Although more tests are needed, it can be used individually!
+
+
+#
+#  Available options:
+#
+#    Environment variables:
+#      CFLAGS
+#
+#      GLIDE           path to Glide3 SDK; used with FX.
+#                      default = $(TOP)/glide3
+#      FX=1            build for 3dfx Glide3. Note that this disables
+#                      compilation of most WMesa code and requires fxMesa.
+#                      As a consequence, you'll need the Win32 Glide3
+#                      library to build any application.
+#                      default = no
+#      ICD=1           build the installable client driver interface
+#                      (windows opengl driver interface)
+#                      default = no
+#      X86=1           optimize for x86 (if possible, use MMX, SSE, 3DNow).
+#                      default = no
+#
+#    Targets:
+#      all:            build GL
+#      clean:          remove object files
+#
+
+
+
+.PHONY: all clean
+.INTERMEDIATE: x86/gen_matypes.exe
+.SUFFIXES: .rc .res
+
+# Set this to the prefix of your build tools, i.e. mingw32-
+TOOLS_PREFIX = mingw32-
+
+TOP = ../../..
+
+LIBDIR = $(TOP)/lib
+
+GLUT_DLL = glut32.dll
+GLUT_IMP = libglut32.a
+GLUT_DEF = glut.def
+
+include $(TOP)/configs/config.mgw
+GLUT_USING_STDCALL ?= 1
+
+
+
+LDLIBS = -L$(LIBDIR) -lwinmm -lgdi32 -luser32 -lopengl32 -lglu32 
+LDFLAGS = -Wl,--out-implib=$(LIBDIR)/$(GLUT_IMP) -Wl,--output-def=$(LIBDIR)/$(GLUT_DEF) 
+
+CFLAGS += -DBUILD_GLUT32 -DGLUT_BUILDING_LIB -DMESA -D_DLL
+
+ifeq ($(GL_USING_STDCALL),0)
+  CFLAGS += -DGL_NO_STDCALL
+endif
+
+ifeq ($(GLUT_USING_STDCALL),1)
+  CFLAGS += -D_STDCALL_SUPPORTED
+  LDFLAGS += -Wl,--add-stdcall-alias
+else
+  CFLAGS += -DGLUT_NO_STDCALL
+endif
+
+CFLAGS += -DNDEBUG -DLIBRARYBUILD -I$(TOP)/include 
+
+CC = gcc
+CXX = g++
+CXXFLAGS = $(CFLAGS)
+
+AR = ar
+ARFLAGS = crus
+
+UNLINK = del $(subst /,\,$(1))
+ifneq ($(wildcard $(addsuffix /rm.exe,$(subst ;, ,$(PATH)))),)
+UNLINK = $(RM) $(1)
+endif
+ifneq ($(wildcard $(addsuffix /rm,$(subst :, ,$(PATH)))),)
+UNLINK = $(RM) $(1)
+endif
+
+HDRS = glutint.h glutstroke.h glutbitmap.h glutwin32.h stroke.h win32_glx.h win32_x11.h
+
+SRCS = \
+       glut_bitmap.c \
+       glut_bwidth.c \
+       glut_cindex.c \
+       glut_cmap.c \
+       glut_cursor.c \
+       glut_dials.c \
+       glut_dstr.c \
+       glut_event.c \
+       glut_ext.c \
+       glut_fbc.c \
+       glut_fullscrn.c \
+       glut_gamemode.c \
+       glut_get.c \
+       glut_init.c \
+       glut_input.c \
+       glut_joy.c \
+       glut_key.c \
+       glut_keyctrl.c \
+       glut_keyup.c \
+       glut_mesa.c \
+       glut_modifier.c \
+       glut_overlay.c \
+       glut_shapes.c \
+       glut_space.c \
+       glut_stroke.c \
+       glut_swap.c \
+       glut_swidth.c \
+       glut_tablet.c \
+       glut_teapot.c \
+       glut_util.c \
+       glut_vidresize.c \
+       glut_warp.c \
+       glut_win.c \
+       glut_winmisc.c \
+       win32_glx.c \
+       win32_menu.c \
+       win32_util.c \
+       win32_winproc.c \
+       win32_x11.c
+       
+
+SRCSSEMIGENS = \
+       glut_8x13.c \
+       glut_9x15.c \
+       glut_hel10.c \
+       glut_hel12.c \
+       glut_hel18.c \
+       glut_mroman.c \
+       glut_roman.c \
+       glut_tr10.c \
+       glut_tr24.c
+
+
+
+SOURCES = $(SRCS) $(SRCSSEMIGENS)
+
+OBJECTS = $(addsuffix .o,$(basename $(SOURCES)))
+
+.c.o:
+       $(CC) -o $@ $(CFLAGS) -c $<
+.cc.o:
+       $(CXX) -o $@ $(CXXFLAGS) -c $<
+
+
+all: $(LIBDIR) $(LIBDIR)/$(GLUT_DLL) $(LIBDIR)/$(GLUT_IMP)
+
+$(LIBDIR):
+       mkdir -p $(LIBDIR)
+
+$(LIBDIR)/$(GLUT_DLL) $(LIBDIR)/$(GLUT_IMP): $(OBJECTS)
+       $(CXX) -shared -fPIC -o $(LIBDIR)/$(GLUT_DLL) $(LDFLAGS) \
+       $^ $(LDLIBS)
+
+
+
+clean:
+       -$(call UNLINK,*.o)
\ No newline at end of file
index deb46c3d8db28fdcc40e60decbe7b3ee0c1b4eef..e93188b86221e6882cf9cb4fdb94ca179d330333 100644 (file)
@@ -18,7 +18,7 @@
 
 /* Set a Fortran callback function. */
 
-void GLUTAPIENTRY
+void APIENTRY
 __glutSetFCB(int which, void *func)
 {
 #ifdef SUPPORT_FORTRAN
@@ -100,7 +100,7 @@ __glutSetFCB(int which, void *func)
 
 /* Get a Fortran callback function. */
 
-void* GLUTAPIENTRY
+void* APIENTRY
 __glutGetFCB(int which)
 {
 #ifdef SUPPORT_FORTRAN
index 6fe09ffe7e708e914b23a38345111c830797966f..a962c780238d17171bac4001bd0a68e2fa50e14d 100644 (file)
 #include <GL/glx.h>
 #endif
 
+#ifndef GLUT_BUILDING_LIB
 #define GLUT_BUILDING_LIB  /* Building the GLUT library itself. */
+#endif
+
 #include <GL/glut.h>
 
 #if defined(MESA) && defined(_WIN32) && !defined(__CYGWIN32__)
index a54bac75fa0af63e7188e757e168cca595599a04..e1fc785ebb7fff95053eb179cab5b12965031014 100644 (file)
@@ -9,6 +9,9 @@
 
 #include "glutint.h"
 #include <sys/timeb.h>
+#ifdef __MINGW32__
+#include <ctype.h>
+#endif
 
 #if defined(_WIN32) && !defined(__CYGWIN32__)
 #include <mmsystem.h>  /* Win32 Multimedia API header. */
index ebec5c055a87cc757efd3750fc1c8a518fb7051e..3b52834bd1c327fe429e8acf5197dc3c741fca4a 100644 (file)
@@ -1,5 +1,5 @@
 # Mesa 3-D graphics library
-# Version:  5.1
+# Version:  7.0
 # 
 # Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
 # 
 #  Email : dborca@users.sourceforge.net
 #  Web   : http://www.geocities.com/dborca
 
+# MinGW core-gl makefile updated for Mesa 7.0
+#
+#  updated : by Heromyth, on 2007-7-21
+#  Email   : zxpmyth@yahoo.com.cn
+#  Bugs    : 1) All the default settings work fine. But the setting X86=1 can't work. 
+#            The others havn't been tested yet.
+#            2) The generated DLLs are *not* compatible with the ones built
+#            with the other compilers like VC8, especially for GLUT. 
+#            3) Although more tests are needed, it can be used individually!
+
 
 #
 #  Available options:
@@ -52,7 +62,6 @@
 #
 
 
-
 .PHONY: all clean
 .INTERMEDIATE: x86/gen_matypes.exe
 .SUFFIXES: .rc .res
@@ -60,6 +69,8 @@
 # Set this to the prefix of your build tools, i.e. mingw32-
 TOOLS_PREFIX = mingw32-
 
+
+
 TOP = ../..
 GLIDE ?= $(TOP)/glide3
 LIBDIR = $(TOP)/lib
@@ -71,11 +82,25 @@ else
   GL_IMP = libopengl32.a
 endif
 
-LDLIBS = -lgdi32
+GL_DEF = gl.def
+
+include $(TOP)/configs/config.mgw
+GL_USING_STDCALL ?= 1
+
+MESA_LIB = libmesa.a
+
+LDLIBS = -lgdi32 -luser32 -liberty
+LDFLAGS = -Wl,--out-implib=$(LIBDIR)/$(GL_IMP) -Wl,--output-def=$(LIBDIR)/gl.def
 
 CC = $(TOOLS_PREFIX)gcc
-CFLAGS += -DBUILD_GL32 -D_OPENGL32_
-CFLAGS += $(INCLUDE_DIRS)
+CFLAGS += -DBUILD_GL32 -D_OPENGL32_ -D_DLL -DMESA_MINWARN -DNDEBUG -D_USRDLL -DGDI_EXPORTS
+
+ifeq ($(GL_USING_STDCALL),1)
+  LDFLAGS += -Wl,--add-stdcall-alias
+else
+  CFLAGS += -DGL_NO_STDCALL
+endif
+
 CFLAGS += -DUSE_EXTERNAL_DXTN_LIB=1
 ifeq ($(FX),1)
   CFLAGS += -I$(GLIDE)/include -DFX
@@ -104,6 +129,8 @@ endif
 
 include sources
 
+CFLAGS += $(INCLUDE_DIRS) 
+
 ifeq ($(X86),1)
 CFLAGS += -DUSE_X86_ASM
 CFLAGS += -DUSE_MMX_ASM
@@ -140,10 +167,9 @@ RESOURCE = $(GL_RES:.rc=.res)
 
 .c.o:
        $(CC) -o $@ $(CFLAGS) -c $<
-.S.o:
-       $(CC) -o $@ $(CFLAGS) -c $<
 .s.o:
        $(CC) -o $@ $(CFLAGS) -x assembler-with-cpp -c $<
+
 .rc.res:
        windres -o $@ -Irc -Ocoff $<
 
@@ -153,9 +179,8 @@ $(LIBDIR):
        mkdir -p $(LIBDIR)
 
 $(LIBDIR)/$(GL_DLL) $(LIBDIR)/$(GL_IMP): $(OBJECTS) $(RESOURCE)
-       $(TOOLS_PREFIX)dllwrap -o $(LIBDIR)/$(GL_DLL) --output-lib $(LIBDIR)/$(GL_IMP) \
-                              --target i386-mingw32 --def $(GL_DEF) -Wl,-enable-stdcall-fixup \
-                              $^ $(LDLIBS)
+       $(CC) -shared -fPIC -o $(LIBDIR)/$(GL_DLL) $(LDFLAGS) \
+       $^ $(LDLIBS)
 
 $(X86_OBJECTS): x86/matypes.h
 
@@ -187,17 +212,21 @@ tnl/t_vtx_x86_gcc.o: tnl/t_vtx_x86_gcc.S
        $(CC) -o $@ $(CFLAGS) -DSTDCALL_API -c $<
 
 clean:
-       -$(call UNLINK,array_cache/*.o)
        -$(call UNLINK,glapi/*.o)
        -$(call UNLINK,main/*.o)
        -$(call UNLINK,math/*.o)
+       -$(call UNLINK,vbo/*.o)
        -$(call UNLINK,shader/*.o)
+       -$(call UNLINK,shader/slang/*.o)
+       -$(call UNLINK,shader/grammar/*.o)
        -$(call UNLINK,sparc/*.o)
        -$(call UNLINK,ppc/*.o)
        -$(call UNLINK,swrast/*.o)
        -$(call UNLINK,swrast_setup/*.o)
        -$(call UNLINK,tnl/*.o)
        -$(call UNLINK,x86/*.o)
+       -$(call UNLINK,x86/rtasm/*.o)
+       -$(call UNLINK,x86-64/*.o)
        -$(call UNLINK,drivers/common/*.o)
        -$(call UNLINK,drivers/glide/*.o)
        -$(call UNLINK,drivers/windows/fx/*.o)
index 6f2314ee8cb7ee6ed10727bc2d505d5e3b25093a..43c0e912bf25540f98cf79f094b1c0e81ebe1de2 100644 (file)
@@ -85,7 +85,7 @@ $(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME)
 depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
        touch depend
        $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \
-               $(ASM_SOURCES) 2>&1 /dev/null
+               $(ASM_SOURCES) 2> /dev/null
 
 
 # Emacs tags
index d785382f39d835c81286284469cad2ce47511091..6e8a5b52180184fc163df96cc4b1bca92e0b86fb 100644 (file)
@@ -434,10 +434,12 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
 
     if (pdp->pClipRects) {
        _mesa_free(pdp->pClipRects); 
+       pdp->pClipRects = NULL;
     }
 
     if (pdp->pBackClipRects) {
        _mesa_free(pdp->pBackClipRects); 
+       pdp->pBackClipRects = NULL;
     }
 
     DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
index 3ad25282d90d599ad71aaba270e26ee91c51b26c..e0d5b2b4876da5a3f3e0373dfa75bd07dcf0b91f 100644 (file)
@@ -380,7 +380,10 @@ static void i810CullFaceFrontFace(GLcontext *ctx, GLenum unused)
 static void i810LineWidth( GLcontext *ctx, GLfloat widthf )
 {
    i810ContextPtr imesa = I810_CONTEXT( ctx );
-   int width = (int)ctx->Line._Width;
+   /* AA, non-AA limits are same */
+   const int width = (int) CLAMP(ctx->Line.Width,
+                                 ctx->Const.MinLineWidth,
+                                 ctx->Const.MaxLineWidth);
 
    imesa->LcsLineWidth = 0;
    if (width & 1) imesa->LcsLineWidth |= LCS_LINEWIDTH_1_0;
@@ -396,7 +399,10 @@ static void i810LineWidth( GLcontext *ctx, GLfloat widthf )
 static void i810PointSize( GLcontext *ctx, GLfloat sz )
 {
    i810ContextPtr imesa = I810_CONTEXT( ctx );
-   int size = (int)ctx->Point._Size;
+   /* AA, non-AA limits are same */
+   const int size = (int) CLAMP(ctx->Point.Size,
+                                ctx->Const.MinPointSize,
+                                ctx->Const.MaxPointSize);
 
    imesa->LcsPointSize = 0;
    if (size & 1) imesa->LcsPointSize |= LCS_LINEWIDTH_1_0;
index 3e09427bb94f631c1fa6efcdf2ac55744a143de2..2c4ee06633d671dc6589481f493c00017b809c43 100644 (file)
@@ -112,7 +112,9 @@ static __inline__ void i810_draw_quad( i810ContextPtr imesa,
 static __inline__ void i810_draw_point( i810ContextPtr imesa,
                                        i810VertexPtr tmp )
 {
-   GLfloat sz = imesa->glCtx->Point._Size * .5;
+   GLfloat sz = 0.5 * CLAMP(imesa->glCtx->Point.Size,
+                            imesa->glCtx->Const.MinPointSize,
+                            imesa->glCtx->Const.MaxPointSize);
    int vertsize = imesa->vertex_size;
    GLuint *vb = i810AllocDmaLow( imesa, 2 * 4 * vertsize );
    int j;
index b0e5f87fc75cc996d469025330aa1951f2536660..cc8a605e50537c21868f96b1e4dd18035b84eb89 100644 (file)
@@ -64,6 +64,7 @@ static void i915_reduced_primitive_state( intelContextPtr intel,
     st1 &= ~ST1_ENABLE;
 
     switch (rprim) {
+    case GL_QUADS: /* from RASTERIZE(GL_QUADS) in t_dd_tritemp.h */
     case GL_TRIANGLES:
        if (intel->ctx.Polygon.StippleFlag &&
           intel->hw_stipple)
index d175870a0c5e3c48bc660049afb70ffd6d98620a..c3030d42b04801944f3124c1eaf87d0d80715b62 100644 (file)
@@ -450,10 +450,16 @@ intelDrawPixels( GLcontext *ctx,
        * wise happily run the fragment program on each pixel in the image).
        */
       struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current;
+   /* can't just set current frag prog to 0 here as on buffer resize
+      we'll get new state checks which will segfault. Remains a hack. */
       ctx->FragmentProgram._Current = NULL;
+      ctx->FragmentProgram._UseTexEnvProgram = GL_FALSE;
+      ctx->FragmentProgram._Active = GL_FALSE;
       _swrast_DrawPixels( ctx, x, y, width, height, format, type,
                           unpack, pixels );
       ctx->FragmentProgram._Current = fpSave;
+      ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE;
+      ctx->FragmentProgram._Active = GL_TRUE;
    }
    else {
       _swrast_DrawPixels( ctx, x, y, width, height, format, type,
index b218929dce727da46ec708763e1ea1d47a27e04e..827acc0c46c494263e703615e2b087ca935d4a72 100644 (file)
@@ -48,6 +48,7 @@ DRIVER_SOURCES = \
        intel_screen.c \
        intel_span.c \
        intel_state.c \
+       intel_surface.c \
        intel_tris.c \
        intel_fbo.c \
        intel_depthstencil.c \
index 49e30141e4343fa7b32fb2ac784c36d8e22cf41a..b6d004b258b9ecd558c7604c14c9009adf56c36f 100644 (file)
@@ -71,6 +71,8 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state)
    _tnl_invalidate_vertex_state(ctx, new_state);
    intel_context(ctx)->NewGLState |= new_state;
 
+   st_invalidate_state(ctx, new_state);
+
    /* Todo: gather state values under which tracked parameters become
     * invalidated, add callbacks for things like
     * ProgramLocalParameters, etc.
index 13ca9aee6bd5b007d85d26575fd26fcf3f6c0759..cc74ceae18010bc144dffbc82a4bdf0246420d0a 100644 (file)
@@ -66,6 +66,7 @@ i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim)
    st1 &= ~ST1_ENABLE;
 
    switch (rprim) {
+   case GL_QUADS: /* from RASTERIZE(GL_QUADS) in t_dd_tritemp.h */
    case GL_TRIANGLES:
       if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple)
          st1 |= ST1_ENABLE;
index 4b2a4acaf98130cf9d59285647c74d8123149f00..72c7b5ae454e9df7898ac75b8a5964f0533cb024 100644 (file)
@@ -250,7 +250,8 @@ intelWindowMoved(struct intel_context *intel)
         flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY;
       }
 
-      if (flags != intel_fb->vblank_flags) {
+      if (flags != intel_fb->vblank_flags && intel_fb->vblank_flags &&
+         !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ)) {
         drmVBlank vbl;
         int i;
 
@@ -261,7 +262,9 @@ intelWindowMoved(struct intel_context *intel)
         }
 
         for (i = 0; i < intel_fb->pf_num_pages; i++) {
-           if (!intel_fb->color_rb[i])
+           if (!intel_fb->color_rb[i] ||
+               (intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <=
+               (1<<23))
               continue;
 
            vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending;
@@ -583,8 +586,9 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
    drm_i915_vblank_swap_t swap;
    GLboolean ret;
 
-   if ((intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) ||
-        intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6))
+   if (!intel_fb->vblank_flags ||
+       (intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) ||
+       intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6))
       return GL_FALSE;
 
    swap.seqtype = DRM_VBLANK_ABSOLUTE;
index f032c97dfbb02382c4fcb27e666f20066492055c..5ab919ecb60605f3409c56d33b2ff2ba4a3f34a9 100644 (file)
 #include "intel_buffer_objects.h"
 #include "intel_fbo.h"
 
+#include "pipe/softpipe/sp_context.h"
+#include "state_tracker/st_public.h"
+
+
 #include "drirenderbuffer.h"
 #include "vblank.h"
 #include "utils.h"
@@ -257,6 +261,9 @@ intelInvalidateState(GLcontext * ctx, GLuint new_state)
    _vbo_InvalidateState(ctx, new_state);
    _tnl_InvalidateState(ctx, new_state);
    _tnl_invalidate_vertex_state(ctx, new_state);
+
+   st_invalidate_state( ctx, new_state );
+
    intel_context(ctx)->NewGLState |= new_state;
 }
 
@@ -504,6 +511,11 @@ intelInitContext(struct intel_context *intel,
       FALLBACK(intel, INTEL_FALLBACK_USER, 1);
    }
 
+
+   st_create_context( &intel->ctx,
+                     softpipe_create() );
+   
+
    return GL_TRUE;
 }
 
@@ -605,12 +617,23 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
       if (intel->ctx.DrawBuffer == &intel_fb->Base) {
 
         if (intel->driDrawable != driDrawPriv) {
-           intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0)
-              ? driGetDefaultVBlankFlags(&intel->optionCache)
-              : VBLANK_FLAG_NO_IRQ;
-           (*dri_interface->getUST) (&intel_fb->swap_ust);
-           driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags,
-                                 &intel_fb->vbl_seq);
+           if (driDrawPriv->pdraw->swap_interval == (unsigned)-1) {
+              int i;
+
+              intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0)
+                 ? driGetDefaultVBlankFlags(&intel->optionCache)
+                : VBLANK_FLAG_NO_IRQ;
+
+              (*dri_interface->getUST) (&intel_fb->swap_ust);
+              driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags,
+                                    &intel_fb->vbl_seq);
+              intel_fb->vbl_waited = intel_fb->vbl_seq;
+
+              for (i = 0; i < 2; i++) {
+                 if (intel_fb->color_rb[i])
+                    intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_seq;
+              }
+           }
         }
       }
 
@@ -660,37 +683,27 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
    if (sarea->width != intel->width ||
        sarea->height != intel->height ||
        sarea->rotation != intel->current_rotation) {
-      
-      void *batchMap = intel->batch->map;
-      
+      int numClipRects = intel->numClipRects;
+
       /*
        * 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
+       * This will essentially drop the outstanding batchbuffer on the floor.
        */
+      intel->numClipRects = 0;
 
-      if (batchMap != NULL) {
-        driBOUnmap(intel->batch->buffer);
-        intel->batch->map = NULL;
-      }
-
-      intel_batchbuffer_reset(intel->batch);
+      if (intel->Fallback)
+        _swrast_flush(&intel->ctx);
 
-      if (batchMap == NULL) {
-        driBOUnmap(intel->batch->buffer);
-        intel->batch->map = NULL;
-      }
+      INTEL_FIREVERTICES(intel);
 
-      /* lose all primitives */
-      intel->prim.primitive = ~0;
-      intel->prim.start_ptr = 0;
-      intel->prim.flush = 0;
+      if (intel->batch->map != intel->batch->ptr)
+        intel_batchbuffer_flush(intel->batch);
 
-      /* re-emit all state */
-      intel->vtbl.lost_hardware(intel);
+      intel->numClipRects = numClipRects;
 
       /* force window update */
       intel->lastStamp = 0;
@@ -724,7 +737,9 @@ void LOCK_HARDWARE( struct intel_context *intel )
                                    BUFFER_BACK_LEFT);
     }
 
-    if (intel_rb && (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) {
+    if (intel_rb && intel_fb->vblank_flags &&
+       !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) &&
+       (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) {
        drmVBlank vbl;
 
        vbl.request.type = DRM_VBLANK_ABSOLUTE;
index 04ca5ae8ba0da25c5725e82d94964f31035065f2..559788f20a9b3f053b716e90f4b86e8ced0bdd80 100644 (file)
@@ -291,6 +291,12 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
       rb->Width = width;
       rb->Height = height;
 
+#if 1
+      /* update the surface's size too */
+      rb->surface->width = width;
+      rb->surface->height = height;
+#endif
+
       /* This sets the Get/PutRow/Value functions */
       intel_set_span_functions(&irb->Base);
 
@@ -362,7 +368,9 @@ intel_new_renderbuffer_fb(GLuint intFormat)
       irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT;
       break;
    default:
-      assert(0);
+      _mesa_problem(NULL,
+                   "Unexpected intFormat in intel_create_renderbuffer");
+      return NULL;
    }
 
    /* intel-specific methods */
@@ -371,7 +379,10 @@ intel_new_renderbuffer_fb(GLuint intFormat)
    irb->Base.GetPointer = intel_get_pointer;
    /* span routines set in alloc_storage function */
 
-   return irb;
+   irb->Base.surface = intel_new_surface(intFormat);
+   irb->Base.surface->rb = irb;
+
+   return &irb->Base;
 }
 
 /**
@@ -399,6 +410,9 @@ intel_new_renderbuffer(GLcontext * ctx, GLuint name)
    irb->Base.GetPointer = intel_get_pointer;
    /* span routines set in alloc_storage function */
 
+   irb->Base.surface = intel_new_surface(0 /*unknown format*/);
+   irb->Base.surface->rb = irb;
+
    return &irb->Base;
 }
 
index 762aac594e8acdbb7f7490459e42c7273f0c6801..7dc39675337701701ca490227bf8bbaf9f99fe21 100644 (file)
 #define INTEL_FBO_H
 
 
+#include "pipe/p_state.h"
+#include "pipe/softpipe/sp_surface.h"
+
+
 struct intel_context;
 struct intel_region;
 
+
 /**
  * Intel framebuffer, derived from gl_framebuffer.
  */
@@ -82,6 +87,8 @@ struct intel_renderbuffer
    GLuint pf_pending;  /**< sequence number of pending flip */
 
    GLuint vbl_pending;   /**< vblank sequence number of pending flip */
+
+   struct intel_surface *surface;
 };
 
 #if 0
@@ -113,5 +120,8 @@ extern struct intel_region *intel_get_rb_region(struct gl_framebuffer *fb,
 
 
 
+extern struct pipe_surface *
+intel_new_surface(GLuint intFormat);
+
 
 #endif /* INTEL_FBO_H */
diff --git a/src/mesa/drivers/dri/i915tex/intel_surface.c b/src/mesa/drivers/dri/i915tex/intel_surface.c
new file mode 100644 (file)
index 0000000..043c5aa
--- /dev/null
@@ -0,0 +1,259 @@
+#include "glheader.h"
+#include "context.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+#include "utils.h"
+#include "main/macros.h"
+
+
+#include "intel_screen.h"
+
+#include "intel_context.h"
+#include "intel_buffers.h"
+#include "intel_regions.h"
+#include "intel_span.h"
+#include "intel_fbo.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "pipe/softpipe/sp_surface.h"
+
+
+/*
+ * XXX a lof of this is a temporary kludge
+ */
+
+/**
+ * Note: the arithmetic/addressing in these functions is a little
+ * tricky since we need to invert the Y axis.
+ */
+
+
+static void
+read_quad_f_swz(struct softpipe_surface *sps, GLint x, GLint y,
+                GLfloat (*rrrr)[QUAD_SIZE])
+{
+   const GLint bytesPerRow = sps->surface.stride * sps->surface.cpp;
+   const GLint invY = sps->surface.height - y - 1;
+   const GLubyte *src = sps->surface.ptr + invY * bytesPerRow + x * sps->surface.cpp;
+   GLfloat *dst = (GLfloat *) rrrr;
+   GLubyte temp[16];
+   GLuint j;
+
+   assert(sps->surface.format == PIPE_FORMAT_U_A8_R8_G8_B8);
+
+   memcpy(temp + 8, src, 8);
+   memcpy(temp + 0, src + bytesPerRow, 8);
+
+   for (j = 0; j < 4; j++) {
+      dst[0 * 4 + j] = UBYTE_TO_FLOAT(temp[j * 4 + 2]); /*R*/
+      dst[1 * 4 + j] = UBYTE_TO_FLOAT(temp[j * 4 + 1]); /*G*/
+      dst[2 * 4 + j] = UBYTE_TO_FLOAT(temp[j * 4 + 0]); /*B*/
+      dst[3 * 4 + j] = UBYTE_TO_FLOAT(temp[j * 4 + 3]); /*A*/
+   }
+}
+
+
+static void
+write_quad_f_swz(struct softpipe_surface *sps, GLint x, GLint y,
+                 GLfloat (*rrrr)[QUAD_SIZE])
+{
+   const GLfloat *src = (const GLfloat *) rrrr;
+   const GLint bytesPerRow = sps->surface.stride * sps->surface.cpp;
+   const GLint invY = sps->surface.height - y - 1;
+   GLubyte *dst = sps->surface.ptr + invY * bytesPerRow + x * sps->surface.cpp;
+   GLubyte temp[16];
+   GLuint j;
+
+   assert(sps->surface.format == PIPE_FORMAT_U_A8_R8_G8_B8);
+
+   for (j = 0; j < 4; j++) {
+      UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + 2], src[0 * 4 + j]); /*R*/
+      UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + 1], src[1 * 4 + j]); /*G*/
+      UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + 0], src[2 * 4 + j]); /*B*/
+      UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + 3], src[3 * 4 + j]); /*A*/
+   }
+
+   memcpy(dst, temp + 8, 8);
+   memcpy(dst + bytesPerRow, temp + 0, 8);
+}
+
+
+
+static void
+read_quad_z24(struct softpipe_surface *sps,
+              GLint x, GLint y, GLuint zzzz[QUAD_SIZE])
+{
+   static const GLuint mask = 0xffffff;
+   const GLint invY = sps->surface.height - y - 1;
+   const GLuint *src
+      = (GLuint *) (sps->surface.ptr
+                    + (invY * sps->surface.stride + x) * sps->surface.cpp);
+
+   assert(sps->surface.format == PIPE_FORMAT_Z24_S8);
+
+   /* extract lower three bytes */
+   zzzz[0] = src[0] & mask;
+   zzzz[1] = src[1] & mask;
+   zzzz[2] = src[-sps->surface.stride] & mask;
+   zzzz[3] = src[-sps->surface.stride + 1] & mask;
+}
+
+static void
+write_quad_z24(struct softpipe_surface *sps,
+               GLint x, GLint y, const GLuint zzzz[QUAD_SIZE])
+{
+   static const GLuint mask = 0xff000000;
+   const GLint invY = sps->surface.height - y - 1;
+   GLuint *dst
+      = (GLuint *) (sps->surface.ptr
+                    + (invY * sps->surface.stride + x) * sps->surface.cpp);
+
+   assert(sps->surface.format == PIPE_FORMAT_Z24_S8);
+
+   /* write lower three bytes */
+   dst[0] = (dst[0] & mask) | zzzz[0];
+   dst[1] = (dst[1] & mask) | zzzz[1];
+   dst -= sps->surface.stride;
+   dst[0] = (dst[0] & mask) | zzzz[2];
+   dst[1] = (dst[1] & mask) | zzzz[3];
+}
+
+
+static void
+read_quad_stencil(struct softpipe_surface *sps,
+                  GLint x, GLint y, GLubyte ssss[QUAD_SIZE])
+{
+   const GLint invY = sps->surface.height - y - 1;
+   const GLuint *src = (const GLuint *) (sps->surface.ptr
+                     + (invY * sps->surface.stride + x) * sps->surface.cpp);
+
+   assert(sps->surface.format == PIPE_FORMAT_Z24_S8);
+
+   /* extract high byte */
+   ssss[0] = src[0] >> 24;
+   ssss[1] = src[1] >> 24;
+   ssss[2] = src[-sps->surface.width] >> 24;
+   ssss[3] = src[-sps->surface.width + 1] >> 24;
+}
+
+static void
+write_quad_stencil(struct softpipe_surface *sps,
+                   GLint x, GLint y, const GLubyte ssss[QUAD_SIZE])
+{
+   static const GLuint mask = 0x00ffffff;
+   const GLint invY = sps->surface.height - y - 1;
+   GLuint *dst = (GLuint *) (sps->surface.ptr
+               + (invY * sps->surface.stride + x) * sps->surface.cpp);
+
+   assert(sps->surface.format == PIPE_FORMAT_Z24_S8);
+
+   /* write high byte */
+   dst[0] = (dst[0] & mask) | (ssss[0] << 24);
+   dst[1] = (dst[1] & mask) | (ssss[1] << 24);
+   dst -= sps->surface.stride;
+   dst[0] = (dst[0] & mask) | (ssss[2] << 24);
+   dst[1] = (dst[1] & mask) | (ssss[3] << 24);
+}
+
+
+static void *
+map_surface_buffer(struct pipe_buffer *pb, GLuint access_mode)
+{
+   struct softpipe_surface *sps = (struct softpipe_surface *) pb;
+   struct intel_renderbuffer *irb = (struct intel_renderbuffer *) sps->surface.rb;
+   assert(access_mode == PIPE_MAP_READ_WRITE);
+
+   /*LOCK_HARDWARE(intel);*/
+
+   if (irb->region) {
+      GET_CURRENT_CONTEXT(ctx);
+      struct intel_context *intel = intel_context(ctx);
+#if 0
+      intelFinish(&intel->ctx);  /* XXX need this? */
+#endif
+      intel_region_map(intel->intelScreen, irb->region);
+   }
+   pb->ptr = irb->region->map;
+
+   sps->surface.stride = irb->region->pitch;
+   sps->surface.cpp = irb->region->cpp;
+   sps->surface.ptr = irb->region->map;
+
+   return pb->ptr;
+}
+
+
+static void
+unmap_surface_buffer(struct pipe_buffer *pb)
+{
+   struct softpipe_surface *sps = (struct softpipe_surface *) pb;
+   struct intel_renderbuffer *irb = (struct intel_renderbuffer *) sps->surface.rb;
+
+   if (irb->region) {
+      GET_CURRENT_CONTEXT(ctx);
+      struct intel_context *intel = intel_context(ctx);
+      intel_region_unmap(intel->intelScreen, irb->region);
+   }
+   pb->ptr = NULL;
+
+   sps->surface.stride = 0;
+   sps->surface.cpp = 0;
+   sps->surface.ptr = NULL;
+
+   /*UNLOCK_HARDWARE(intel);*/
+}
+
+
+struct pipe_surface *
+intel_new_surface(GLuint intFormat)
+{
+   struct softpipe_surface *sps = CALLOC_STRUCT(softpipe_surface);
+   if (!sps)
+      return NULL;
+
+   sps->surface.width = 0; /* set in intel_alloc_renderbuffer_storage() */
+   sps->surface.height = 0;
+
+   if (intFormat == GL_RGBA8) {
+      sps->surface.format = PIPE_FORMAT_U_A8_R8_G8_B8;
+      sps->read_quad_f_swz = read_quad_f_swz;
+      sps->write_quad_f_swz = write_quad_f_swz;
+   }
+   else if (intFormat == GL_RGB5) {
+      sps->surface.format = PIPE_FORMAT_U_R5_G6_B5;
+
+   }
+   else if (intFormat == GL_DEPTH_COMPONENT16) {
+      sps->surface.format = PIPE_FORMAT_U_Z16;
+
+   }
+   else if (intFormat == GL_DEPTH24_STENCIL8_EXT) {
+      sps->surface.format = PIPE_FORMAT_Z24_S8;
+      sps->read_quad_z = read_quad_z24;
+      sps->write_quad_z = write_quad_z24;
+      sps->read_quad_stencil = read_quad_stencil;
+      sps->write_quad_stencil = write_quad_stencil;
+   }
+   else {
+      /* TBD / unknown */
+
+   }
+
+   sps->surface.buffer.map = map_surface_buffer;
+   sps->surface.buffer.unmap = unmap_surface_buffer;
+
+   return &sps->surface;
+}
+
+
+
+struct pipe_surface *
+xmesa_get_stencil_surface(GLcontext *ctx)
+{
+   /* XXX fix */
+   return NULL;
+}
+
+
+
index bfac52d765b370e2086e5d29845b3af8f7d08ff7..9a6e5f5f192ae7097e5069bf43dde34756d94162 100644 (file)
@@ -173,7 +173,8 @@ static void upload_sf_unit( struct brw_context *brw )
       
 
    /* _NEW_LINE */
-   sf.sf6.line_width = brw->attribs.Line->_Width * (1<<1);
+   /* XXX use ctx->Const.Min/MaxLineWidth here */
+   sf.sf6.line_width = CLAMP(brw->attribs.Line->Width, 1.0, 5.0) * (1<<1);
 
    sf.sf6.line_endcap_aa_region_width = 1;
    if (brw->attribs.Line->SmoothFlag)
@@ -183,7 +184,8 @@ static void upload_sf_unit( struct brw_context *brw )
 
    /* _NEW_POINT */
    sf.sf6.point_rast_rule = 1; /* opengl conventions */
-   sf.sf7.point_size = brw->attribs.Point->_Size * (1<<3);
+   /* XXX clamp max depends on AA vs. non-AA */
+   sf.sf7.point_size = CLAMP(brw->attribs.Point->Size, 1.0, 3.0) * (1<<3);
    sf.sf7.use_point_size_state = !brw->attribs.Point->_Attenuated;
       
    /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
index 173d1d5b6c232f8a7491a2be5d4ac2272ccba011..f88cbb2328dfc3e2a35bff2d6da2ee97ba966000 100644 (file)
@@ -532,12 +532,15 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
                                  GLuint dst_offset,
                                  GLboolean dst_tiled,
                                  GLshort x, GLshort y, 
-                                 GLshort w, GLshort h)
+                                 GLshort w, GLshort h,
+                                 GLenum logic_op)
 {
    struct xy_setup_blit setup;
    struct xy_text_immediate_blit text;
    int dwords = ((src_size + 7) & ~7) / 4;
 
+   assert( logic_op - GL_CLEAR >= 0 );
+   assert( logic_op - GL_CLEAR < 0x10 );
 
    if (w < 0 || h < 0) 
       return;
@@ -561,7 +564,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
    setup.br0.length = (sizeof(setup) / sizeof(int)) - 2;
       
    setup.br13.dest_pitch = dst_pitch;
-   setup.br13.rop = 0xcc;
+   setup.br13.rop = translate_raster_op(logic_op);
    setup.br13.color_depth = (cpp == 4) ? BR13_8888 : BR13_565;
    setup.br13.clipping_enable = 0;
    setup.br13.mono_source_transparency = 1;
index 8b0cc65243cc617fba93e269387a8e4625acdfe9..e361545c8fab316c2e4315734fd69a1ec7a82642 100644 (file)
@@ -72,6 +72,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
                                  GLuint dst_offset,
                                  GLboolean dst_tiled,
                                  GLshort dst_x, GLshort dst_y, 
-                                 GLshort w, GLshort h);
+                                 GLshort w, GLshort h,
+                                 GLenum logic_op );
 
 #endif
index 5841afaa3ef9ec6395d76901addf1a9b92af363a..421fcc5e511651ae96845a1f5ccdf0bf53ad686d 100644 (file)
@@ -260,7 +260,9 @@ do_blit_bitmap( GLcontext *ctx,
               int h = MIN2(DY, box_h - py);
               int w = MIN2(DX, box_w - px); 
               GLuint sz = align(align(w,8) * h, 64)/8;
-           
+              GLenum logic_op = ctx->Color.ColorLogicOpEnabled ?
+                 ctx->Color.LogicOp : GL_COPY;
+
               assert(sz <= sizeof(stipple));
               memset(stipple, 0, sz);
 
@@ -288,7 +290,8 @@ do_blit_bitmap( GLcontext *ctx,
                                                  dst->tiled,
                                                  rect.x1 + px,
                                                  rect.y2 - (py + h),
-                                                 w, h);
+                                                 w, h,
+                                                 logic_op);
            } 
         } 
       }
index 75cf0e2ed2d41c46c1c237d161ba8ee91fb1c654..248fa2a9a29c54d95184d621eaefb046858b320b 100644 (file)
@@ -103,7 +103,7 @@ void TAG(translate_vertex)(GLcontext *ctx,
 
    assert( p + 1 - (CARD32 *)src == 10 );
         
-   dst->pointSize = ctx->Point._Size;
+   dst->pointSize = ctx->Point.Size;
 }
 
 
index 08cc1849a12dfcdb918cbfec3e383bbd0942338b..369f610442890854ddfc5e65d6e783ec62602ebf 100644 (file)
@@ -673,7 +673,10 @@ static __inline void mach64_draw_line( mach64ContextPtr mmesa,
 #if MACH64_NATIVE_VTXFMT
    GLcontext *ctx = mmesa->glCtx;
    const GLuint vertsize = mmesa->vertex_size;
-   GLint width = (GLint)(mmesa->glCtx->Line._Width * 2.0); /* 2 fractional bits for hardware */
+   /* 2 fractional bits for hardware: */
+   const int width = (int) (2.0 * CLAMP(mmesa->glCtx->Line.Width,
+                                        mmesa->glCtx->Const.MinLineWidth,
+                                        mmesa->glCtx->Const.MaxLineWidth));
    GLfloat ooa;
    GLuint *pxy0, *pxy1;
    GLuint xy0old, xy0, xy1old, xy1;
@@ -691,9 +694,6 @@ static __inline void mach64_draw_line( mach64ContextPtr mmesa,
       mach64_print_vertex( ctx, v1 );
    }
   
-   if( !width )
-      width = 1;       /* round to the nearest supported width */
-      
    pxy0 = &v0->ui[xyoffset];
    xy0old = *pxy0;
    xy0 = LE32_IN( &xy0old );
@@ -961,7 +961,10 @@ static __inline void mach64_draw_point( mach64ContextPtr mmesa,
 #if MACH64_NATIVE_VTXFMT
    GLcontext *ctx = mmesa->glCtx;
    const GLuint vertsize = mmesa->vertex_size;
-   GLint sz = (GLint)(mmesa->glCtx->Point._Size * 2.0); /* 2 fractional bits for hardware */
+   /* 2 fractional bits for hardware: */
+   GLint sz = (GLint) (2.0 * CLAMP(mmesa->glCtx->Point.Size,
+                                   ctx->Const.MinPointSize,
+                                   ctx->Const.MaxPointSize));
    GLfloat ooa;
    GLuint *pxy;
    GLuint xyold, xy;
index 2b7ea05b142cbba262508e660c13e4494ed1ea06..91b413ae760872b8adc108dbdd6a3ce23cf6e61c 100644 (file)
@@ -104,8 +104,10 @@ static void __inline__ mga_draw_quad( mgaContextPtr mmesa,
 static __inline__ void mga_draw_point( mgaContextPtr mmesa,
                                        mgaVertexPtr tmp )
 {
-   GLfloat sz = mmesa->glCtx->Point._Size * .5;
-   int vertex_size = mmesa->vertex_size;
+   const GLfloat sz = 0.5 * CLAMP(mmesa->glCtx->Point.Size,
+                                  mmesa->glCtx->Const.MinPointSize,
+                                  mmesa->glCtx->Const.MaxPointSize);
+   const int vertex_size = mmesa->vertex_size;
    GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
    int j;
    
@@ -165,7 +167,9 @@ static __inline__ void mga_draw_line( mgaContextPtr mmesa,
    GLuint vertex_size = mmesa->vertex_size;
    GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
    GLfloat dx, dy, ix, iy;
-   GLfloat width = mmesa->glCtx->Line._Width;
+   const GLfloat width = CLAMP(mmesa->glCtx->Line.Width,
+                               mmesa->glCtx->Const.MinLineWidth,
+                               mmesa->glCtx->Const.MaxLineWidth);
    GLint j;
 
 #if 0
index 6a2c2013e34b62d9847afb9f0a1aaa80030a7b2a..d498f616c908358553760d26c3888540b95c0698 100644 (file)
@@ -69,7 +69,7 @@ void
 nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem)
 {
    nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-   drm_nouveau_mem_free_t memf;
+   struct drm_nouveau_mem_free memf;
 
    if (NOUVEAU_DEBUG & DEBUG_MEM)  {
       fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n",
@@ -78,8 +78,8 @@ nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem)
 
    if (mem->map)
       drmUnmap(mem->map, mem->size);
-   memf.flags         = mem->type;
-   memf.region_offset = mem->offset;
+   memf.flags  = mem->type;
+   memf.offset = mem->offset;
    drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf, sizeof(memf));
    FREE(mem);
 }
@@ -88,7 +88,7 @@ nouveau_mem *
 nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align)
 {
    nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-   drm_nouveau_mem_alloc_t mema;
+   struct drm_nouveau_mem_alloc mema;
    nouveau_mem *mem;
    int ret;
 
@@ -111,7 +111,7 @@ nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align)
       FREE(mem);
       return NULL;
    }
-   mem->offset = mema.region_offset;
+   mem->offset = mema.offset;
    mem->type   = mema.flags;
 
    if (NOUVEAU_DEBUG & DEBUG_MEM)  {
@@ -120,7 +120,7 @@ nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align)
    }
 
    if (type & NOUVEAU_MEM_MAPPED)
-      ret = drmMap(nmesa->driFd, mem->offset, mem->size, &mem->map);
+      ret = drmMap(nmesa->driFd, mema.map_handle, mem->size, &mem->map);
    if (ret) {
       mem->map = NULL;
       nouveau_mem_free(ctx, mem);
@@ -135,12 +135,7 @@ 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->gart_phys;
-   else
-      return 0xDEADF00D;
+   return mem->offset;
 }
 
 static GLboolean
index d96b00242cd3be6ef3cc171abd2a98e80a74149d..44392c0267cd25d2415102e13a942efa208547b2 100644 (file)
@@ -180,7 +180,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
        driParseConfigFiles (&nmesa->optionCache, &screen->optionCache,
                        screen->driScreen->myNum, "nouveau");
 
-       nmesa->sarea = (drm_nouveau_sarea_t *)((char *)sPriv->pSAREA +
+       nmesa->sarea = (struct drm_nouveau_sarea *)((char *)sPriv->pSAREA +
                        screen->sarea_priv_offset);
 
        /* Enable any supported extensions */
@@ -224,6 +224,8 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
                        nv04TriInitFunctions( ctx );
                        break;
                case NV_10:
+               case NV_11:
+               case NV_17:
                case NV_20:
                case NV_30:
                case NV_40:
index 10d2ed6e172fbc37eee6f442fe762fb183f2d102..9a0be2cb2a57dee36d38c7611e31a899333b7bea 100644 (file)
@@ -109,12 +109,12 @@ typedef struct nouveau_context {
        uint64_t gart_size;
 
        /* Channel synchronisation */
-       drm_nouveau_notifier_alloc_t *syncNotifier;
+       struct drm_nouveau_notifier_alloc *syncNotifier;
 
        /* ARB_occlusion_query / EXT_timer_query */
        GLuint            query_object_max;
        GLboolean *       query_alloc;
-       drm_nouveau_notifier_alloc_t *queryNotifier;
+       struct drm_nouveau_notifier_alloc *queryNotifier;
 
        /* Additional hw-specific functions */
        nouveau_hw_func hw_func;
@@ -168,7 +168,7 @@ typedef struct nouveau_context {
        nouveauShader *passthrough_fp;
 
        nouveauScreenRec *screen;
-       drm_nouveau_sarea_t *sarea;
+       struct drm_nouveau_sarea *sarea;
 
        __DRIcontextPrivate  *driContext;    /* DRI context */
        __DRIscreenPrivate   *driScreen;     /* DRI screen */
index 00956aa8f8b312655083a2e66c9f638d65663c5d..ddc9535624b80f2394982a5833da396e56511abf 100644 (file)
@@ -41,7 +41,7 @@ GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa,
                             unsigned int      param,
                             uint64_t*         value)
 {
-       drm_nouveau_getparam_t getp;
+       struct drm_nouveau_getparam getp;
 
        getp.param = param;
        if (!value || drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_GETPARAM,
@@ -56,7 +56,7 @@ GLboolean nouveauDRMSetParam(nouveauContextPtr nmesa,
                             unsigned int      param,
                             uint64_t          value)
 {
-       drm_nouveau_setparam_t setp;
+       struct drm_nouveau_setparam setp;
 
        setp.param = param;
        setp.value = value;
index e9320918f9fca480f84aab7f93a14df64433abba..7b5e96b4c2615e764fc3b9b92634056fa85fc2be 100644 (file)
@@ -98,7 +98,7 @@ void nouveauWaitForIdle(nouveauContextPtr nmesa)
 // here we call the fifo initialization ioctl and fill in stuff accordingly
 GLboolean nouveauFifoInit(nouveauContextPtr nmesa)
 {
-       drm_nouveau_fifo_alloc_t fifo_init;
+       struct drm_nouveau_fifo_alloc fifo_init;
        int i, ret;
 
 #ifdef NOUVEAU_RING_DEBUG
index c119d14dd751407169e5d83f42999587e5d72598..aa86c9e783841fa44d6e97c9d7451bf84a99bd31 100644 (file)
@@ -44,7 +44,7 @@ void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags )
 {
    __DRIdrawablePrivate *dPriv = nmesa->driDrawable;
    __DRIscreenPrivate *sPriv = nmesa->driScreen;
-   drm_nouveau_sarea_t *sarea = nmesa->sarea;
+   struct drm_nouveau_sarea *sarea = nmesa->sarea;
 
    drmGetLock( nmesa->driFd, nmesa->hHWContext, flags );
 
index 69f8dbf7946499f2edb268af04e50bf2f04040d6..a143488e8d5913e66197a9b4baad3dc5dcee4033 100644 (file)
@@ -7,7 +7,7 @@
 GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa,
                                     uint32_t handle, int class)
 {
-       drm_nouveau_grobj_alloc_t cto;
+       struct drm_nouveau_grobj_alloc cto;
        int ret;
 
        cto.channel = nmesa->fifo.channel;
@@ -34,10 +34,13 @@ void nouveauObjectInit(nouveauContextPtr nmesa)
        nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d);
        if (nmesa->screen->card->type>=NV_10) {
                nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D);
-               nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT);
        } else {
                nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D);
                nouveauCreateContextObject(nmesa, NvCtxSurf3D, NV04_CONTEXT_SURFACES_3D);
+       }
+       if (nmesa->screen->card->type>=NV_11) {
+               nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT);
+       } else {
                nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT);
        }
        nouveauCreateContextObject(nmesa, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT);
index bc7f39b042a6f4d42f34bf4fd33ad9c486a89340..69b0691bb7b49f53e8c6f8e719b1d47f3efc49a5 100644 (file)
@@ -328,7 +328,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc
        static const __DRIversion ddx_expected = { 1, 2, 0 };
        static const __DRIversion dri_expected = { 4, 0, 0 };
        static const __DRIversion drm_expected = { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
-#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 7
+#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 9
 #error nouveau_drm.h version doesn't match expected version
 #endif
        dri_interface = interface;
index 7cb805902a7553708aae3e217e530743f94444f0..f618dcfc99b5b5f079c5551c8cd72bade8d6c045 100644 (file)
@@ -162,6 +162,8 @@ void nouveauDDInitState(nouveauContextPtr nmesa)
             nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
             break;
         case NV_10:
+        case NV_11:
+        case NV_17:
             nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
             break;
         case NV_20:
index 1d1eeede18b650b4037ec354fe8fa8edfd0c607f..8abc847e1e2f1845e91e9f2f8f7c3c89eeca3028 100644 (file)
        nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \
        volatile uint32_t *__v = (void*)nmesa->notifier_block + notifier->offset
 
-drm_nouveau_notifier_alloc_t *
+struct drm_nouveau_notifier_alloc *
 nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count)
 {
        nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-       drm_nouveau_notifier_alloc_t *notifier;
+       struct drm_nouveau_notifier_alloc *notifier;
        int ret;
 
 #ifdef NOUVEAU_RING_DEBUG
@@ -69,14 +69,16 @@ nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count)
 }
 
 void
-nouveau_notifier_destroy(GLcontext *ctx, drm_nouveau_notifier_alloc_t *notifier)
+nouveau_notifier_destroy(GLcontext *ctx,
+                        struct drm_nouveau_notifier_alloc *notifier)
 {
        /*XXX: free notifier object.. */
        FREE(notifier);
 }
 
 void
-nouveau_notifier_reset(GLcontext *ctx, drm_nouveau_notifier_alloc_t *notifier,
+nouveau_notifier_reset(GLcontext *ctx,
+                      struct drm_nouveau_notifier_alloc *notifier,
                       GLuint id)
 {
        NOTIFIER(n);
@@ -93,7 +95,8 @@ nouveau_notifier_reset(GLcontext *ctx, drm_nouveau_notifier_alloc_t *notifier,
 }
 
 GLuint
-nouveau_notifier_status(GLcontext *ctx, drm_nouveau_notifier_alloc_t *notifier,
+nouveau_notifier_status(GLcontext *ctx,
+                       struct drm_nouveau_notifier_alloc *notifier,
                        GLuint id)
 {
        NOTIFIER(n);
@@ -103,7 +106,8 @@ nouveau_notifier_status(GLcontext *ctx, drm_nouveau_notifier_alloc_t *notifier,
 
 GLuint
 nouveau_notifier_return_val(GLcontext *ctx,
-                           drm_nouveau_notifier_alloc_t *notifier, GLuint id)
+                           struct drm_nouveau_notifier_alloc *notifier,
+                           GLuint id)
 {
        NOTIFIER(n);
 
@@ -112,8 +116,8 @@ nouveau_notifier_return_val(GLcontext *ctx,
 
 GLboolean
 nouveau_notifier_wait_status(GLcontext *ctx,
-                            drm_nouveau_notifier_alloc_t *notifier, GLuint id,
-                            GLuint status, GLuint timeout)
+                            struct drm_nouveau_notifier_alloc *notifier,
+                            GLuint id, GLuint status, GLuint timeout)
 {
        NOTIFIER(n);
        unsigned int time = 0;
@@ -146,7 +150,8 @@ nouveau_notifier_wait_status(GLcontext *ctx,
 
 void
 nouveau_notifier_wait_nop(GLcontext *ctx,
-                         drm_nouveau_notifier_alloc_t *notifier, GLuint subc)
+                         struct drm_nouveau_notifier_alloc *notifier,
+                         GLuint subc)
 {
        NOTIFIER(n);
        GLboolean ret;
index b56cc5fb544a14483af7ce018dd97ea0a4d83cb6..b76af172762d6537b53dfe767c889744f8cee6ce 100644 (file)
 #define NV_NOTIFY                                                     0x00000104
 #define NV_NOTIFY_STYLE_WRITE_ONLY                                             0
 
-extern drm_nouveau_notifier_alloc_t *
+extern struct drm_nouveau_notifier_alloc *
 nouveau_notifier_new(GLcontext *, GLuint handle, GLuint count);
 extern void 
-nouveau_notifier_destroy(GLcontext *, drm_nouveau_notifier_alloc_t *);
+nouveau_notifier_destroy(GLcontext *, struct drm_nouveau_notifier_alloc *);
 extern void
-nouveau_notifier_reset(GLcontext *, drm_nouveau_notifier_alloc_t *, GLuint id);
+nouveau_notifier_reset(GLcontext *, struct drm_nouveau_notifier_alloc *,
+                      GLuint id);
 extern GLuint
-nouveau_notifier_status(GLcontext *, drm_nouveau_notifier_alloc_t *, GLuint id);
+nouveau_notifier_status(GLcontext *, struct drm_nouveau_notifier_alloc *,
+                       GLuint id);
 extern GLuint
-nouveau_notifier_return_val(GLcontext *, drm_nouveau_notifier_alloc_t *,
+nouveau_notifier_return_val(GLcontext *, struct drm_nouveau_notifier_alloc *,
                            GLuint id);
 extern GLboolean
-nouveau_notifier_wait_status(GLcontext *, drm_nouveau_notifier_alloc_t *,
+nouveau_notifier_wait_status(GLcontext *, struct drm_nouveau_notifier_alloc *,
                             GLuint id, GLuint status, GLuint timeout);
 extern void
-nouveau_notifier_wait_nop(GLcontext *ctx, drm_nouveau_notifier_alloc_t *,
+nouveau_notifier_wait_nop(GLcontext *ctx, struct drm_nouveau_notifier_alloc *,
                          GLuint subc);
 
 extern GLboolean nouveauSyncInitFuncs(GLcontext *ctx);
index 5f304ccab9251db3530b1d583e757591684802ef..47c4b14ba6b68fc4dc4ea5205d2b53e7ca39e795 100644 (file)
@@ -697,8 +697,7 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa)
        BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1);
        OUT_RING(0);
 
-       /* not for nv10, only for >= nv11 */
-       if ((nmesa->screen->card->id>>4) >= 0x11) {
+       if (nmesa->screen->card->type >= NV_11) {
                BEGIN_RING_SIZE(NvSub3D, 0x120, 3);
                OUT_RING(0);
                OUT_RING(1);
@@ -739,11 +738,11 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color,
        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);
+       /*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);
+       OUT_RING_CACHEf (0.0);*/
 
        return GL_TRUE;
 }
index 4576c1ede4d1273184b8fe25f8621fe8a5634660..611469b6e413c2f01b81141ba86a395643c45421 100644 (file)
@@ -58,7 +58,7 @@ 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)
+       if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17))
                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);
@@ -66,7 +66,7 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t pri
                BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1);
        OUT_RING(primitive);
 
-       if (nmesa->screen->card->type==NV_10)
+       if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17))
                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);
@@ -76,7 +76,7 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t pri
 
 inline void nv10FinishPrimitive(struct nouveau_context *nmesa)
 {
-       if (nmesa->screen->card->type==NV_10)
+       if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17))
                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);
@@ -454,7 +454,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
        /* 
         * Tell the hardware about the vertex format
         */
-       if (nmesa->screen->card->type==NV_10) {
+       if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) {
                int size;
 
 #define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2
index 3d8d83a865ac3afec9f834591a440482c2042c94..ccf2f6148b4908d41403dc3276eb3feaeb628eb8 100644 (file)
@@ -568,10 +568,10 @@ static void nv20Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
           y += nmesa->drawY;
        }
 
-        BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 1);
+        /*BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 1);
         OUT_RING_CACHE((w << 16) | x );
         BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_Y2_Y1, 1);
-        OUT_RING_CACHE((h << 16) | y );
+        OUT_RING_CACHE((h << 16) | y );*/
 
 }
 
@@ -764,11 +764,11 @@ static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color,
        }
 
        /* Always set to bottom left of buffer */
-       BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4);
+       /*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);
+       OUT_RING_CACHEf (0.0);*/
 
        return GL_TRUE;
 }
index 2115799b9b6f0402ec3881e79385e25300961b4c..1d975ecd57d679af5f6f061ee593c0e6a61c5ba9 100644 (file)
@@ -772,9 +772,11 @@ static void r200LineWidth( GLcontext *ctx, GLfloat widthf )
    R200_STATECHANGE( rmesa, set );
 
    /* Line width is stored in U6.4 format.
+    * Same min/max limits for AA, non-AA lines.
     */
    rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= ~0xffff;
-   rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)(ctx->Line._Width * 16.0);
+   rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)
+      (CLAMP(widthf, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth) * 16.0);
 
    if ( widthf > 1.0 ) {
       rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_WIDELINE_ENABLE;
index 6615bc79fb3edc10153d12a37665dea909c12a0d..be6909724a380081b28e4351ff6ae4bcb91566c7 100644 (file)
@@ -568,19 +568,10 @@ struct r300_vertex_shader_fragment {
        union {
                GLuint d[VSF_MAX_FRAGMENT_LENGTH];
                float f[VSF_MAX_FRAGMENT_LENGTH];
-               VERTEX_SHADER_INSTRUCTION i[VSF_MAX_FRAGMENT_LENGTH / 4];
+               GLuint i[VSF_MAX_FRAGMENT_LENGTH];
        } body;
 };
 
-#define VSF_DEST_PROGRAM       0x0
-#define VSF_DEST_MATRIX0       0x200
-#define VSF_DEST_MATRIX1       0x204
-#define VSF_DEST_MATRIX2       0x208
-#define VSF_DEST_VECTOR0       0x20c
-#define VSF_DEST_VECTOR1       0x20d
-#define VSF_DEST_UNKNOWN1      0x400
-#define VSF_DEST_UNKNOWN2      0x406
-
 struct r300_vertex_shader_state {
        struct r300_vertex_shader_fragment program;
 };
index 229439dfa871e6673a544133283b0d90774b0a29..424bf44e595159dbe48d59d733bc2f1ca087cc93 100644 (file)
@@ -299,13 +299,14 @@ GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten)
        if (OutputsWritten & (1 << VERT_RESULT_COL1))
                ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
 
-#if 0
-       if (OutputsWritten & (1 << VERT_RESULT_BFC0))
-               ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT;
-
-       if (OutputsWritten & (1 << VERT_RESULT_BFC1))
-               ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;
+       if (OutputsWritten & (1 << VERT_RESULT_BFC0)
+           || OutputsWritten & (1 << VERT_RESULT_BFC1))
+               ret |=
+                   R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT |
+                   R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT |
+                   R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;
 
+#if 0
        if (OutputsWritten & (1 << VERT_RESULT_FOGC)) ;
 #endif
 
index e59919be493cc1e3724e157af2e62800f42bdce3..1baa74c5269e6d929d2381aa03db653cdc8c1533 100644 (file)
@@ -282,9 +282,32 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 #define R300_VAP_PVS_UPLOAD_ADDRESS         0x2200
 #       define R300_PVS_UPLOAD_PROGRAM           0x00000000
+/* gap */
 #       define R300_PVS_UPLOAD_PARAMETERS        0x00000200
+/* gap */
+#       define R300_PVS_UPLOAD_CLIP_PLANE0       0x00000400
+#       define R300_PVS_UPLOAD_CLIP_PLANE1       0x00000401
+#       define R300_PVS_UPLOAD_CLIP_PLANE2       0x00000402
+#       define R300_PVS_UPLOAD_CLIP_PLANE3       0x00000403
+#       define R300_PVS_UPLOAD_CLIP_PLANE4       0x00000404
+#       define R300_PVS_UPLOAD_CLIP_PLANE5       0x00000405
 #       define R300_PVS_UPLOAD_POINTSIZE         0x00000406
 
+/*
+ * These are obsolete defines form r300_context.h, but they might give some
+ * clues when investigating the addresses further...
+ */
+#if 0
+#define VSF_DEST_PROGRAM        0x0
+#define VSF_DEST_MATRIX0        0x200
+#define VSF_DEST_MATRIX1        0x204
+#define VSF_DEST_MATRIX2        0x208
+#define VSF_DEST_VECTOR0        0x20c
+#define VSF_DEST_VECTOR1        0x20d
+#define VSF_DEST_UNKNOWN1       0x400
+#define VSF_DEST_UNKNOWN2       0x406
+#endif
+
 /* gap */
 
 #define R300_VAP_PVS_UPLOAD_DATA            0x2208
index b5cf21d644a32afe1a84f27a1c3467d67766129a..088216c76ee952467047b7ff99ca9ffef3730cf3 100644 (file)
@@ -82,6 +82,8 @@ static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4])
 
        rmesa->hw.blend_color.cmd[1] = PACK_COLOR_8888(color[3], color[0],
                                                       color[1], color[2]);
+       rmesa->hw.blend_color.cmd[2] = 0;
+       rmesa->hw.blend_color.cmd[3] = 0;
 }
 
 /**
@@ -317,20 +319,34 @@ static void r300UpdateCulling(GLcontext * ctx)
        r300ContextPtr r300 = R300_CONTEXT(ctx);
        uint32_t val = 0;
 
-       R300_STATECHANGE(r300, cul);
        if (ctx->Polygon.CullFlag) {
-               if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
-                       val = R300_CULL_FRONT | R300_CULL_BACK;
-               else if (ctx->Polygon.CullFaceMode == GL_FRONT)
+               switch (ctx->Polygon.CullFaceMode) {
+               case GL_FRONT:
                        val = R300_CULL_FRONT;
-               else
+                       break;
+               case GL_BACK:
                        val = R300_CULL_BACK;
+                       break;
+               case GL_FRONT_AND_BACK:
+                       val = R300_CULL_FRONT | R300_CULL_BACK;
+                       break;
+               default:
+                       break;
+               }
+       }
 
-               if (ctx->Polygon.FrontFace == GL_CW)
-                       val |= R300_FRONT_FACE_CW;
-               else
-                       val |= R300_FRONT_FACE_CCW;
+       switch (ctx->Polygon.FrontFace) {
+       case GL_CW:
+               val |= R300_FRONT_FACE_CW;
+               break;
+       case GL_CCW:
+               val |= R300_FRONT_FACE_CCW;
+               break;
+       default:
+               break;
        }
+
+       R300_STATECHANGE(r300, cul);
        r300->hw.cul.cmd[R300_CUL_CULL] = val;
 }
 
@@ -344,6 +360,20 @@ static void r300SetEarlyZState(GLcontext * ctx)
        r300ContextPtr r300 = R300_CONTEXT(ctx);
 
        R300_STATECHANGE(r300, zstencil_format);
+       switch (ctx->Visual.depthBits) {
+       case 16:
+               r300->hw.zstencil_format.cmd[1] = R300_DEPTH_FORMAT_16BIT_INT_Z;
+               break;
+       case 24:
+               r300->hw.zstencil_format.cmd[1] = R300_DEPTH_FORMAT_24BIT_INT_Z;
+               break;
+       default:
+               fprintf(stderr, "Error: Unsupported depth %d... exiting\n", ctx->Visual.depthBits);
+               _mesa_exit(-1);
+       }
+
+       // r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
+
        if (ctx->Color.AlphaEnabled && ctx->Color.AlphaFunc != GL_ALWAYS)
                /* disable early Z */
                r300->hw.zstencil_format.cmd[2] = R300_EARLY_Z_DISABLE;
@@ -355,6 +385,9 @@ static void r300SetEarlyZState(GLcontext * ctx)
                        /* disable early Z */
                        r300->hw.zstencil_format.cmd[2] = R300_EARLY_Z_DISABLE;
        }
+
+       r300->hw.zstencil_format.cmd[3] = 0x00000003;
+       r300->hw.zstencil_format.cmd[4] = 0x00000000;
 }
 
 static void r300SetAlphaState(GLcontext * ctx)
@@ -403,6 +436,7 @@ static void r300SetAlphaState(GLcontext * ctx)
 
        R300_STATECHANGE(r300, at);
        r300->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc;
+       r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
 
        r300SetEarlyZState(ctx);
 }
@@ -513,6 +547,9 @@ static void r300UpdatePolygonMode(GLcontext * ctx)
                R300_STATECHANGE(r300, polygon_mode);
                r300->hw.polygon_mode.cmd[1] = hw_mode;
        }
+
+       r300->hw.polygon_mode.cmd[2] = 0x00000001;
+       r300->hw.polygon_mode.cmd[3] = 0x00000000;
 }
 
 /**
@@ -696,8 +733,8 @@ static void r300Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param)
 static void r300PointSize(GLcontext * ctx, GLfloat size)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
-
-       size = ctx->Point._Size;
+        /* same size limits for AA, non-AA points */
+       size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
 
        R300_STATECHANGE(r300, ps);
        r300->hw.ps.cmd[R300_PS_POINTSIZE] =
@@ -712,8 +749,9 @@ static void r300LineWidth(GLcontext * ctx, GLfloat widthf)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
 
-       widthf = ctx->Line._Width;
-
+       widthf = CLAMP(widthf,
+                       ctx->Const.MinPointSize,
+                       ctx->Const.MaxPointSize);
        R300_STATECHANGE(r300, lcntl);
        r300->hw.lcntl.cmd[1] =
            R300_LINE_CNT_HO | R300_LINE_CNT_VE | (int)(widthf * 6.0);
@@ -762,6 +800,7 @@ static void r300ShadeModel(GLcontext * ctx, GLenum mode)
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
 
        R300_STATECHANGE(rmesa, shade);
+       rmesa->hw.shade.cmd[1] = 0x00000002;
        switch (mode) {
        case GL_FLAT:
                rmesa->hw.shade.cmd[2] = R300_RE_SHADE_MODEL_FLAT;
@@ -772,6 +811,8 @@ static void r300ShadeModel(GLcontext * ctx, GLenum mode)
        default:
                return;
        }
+       rmesa->hw.shade.cmd[3] = 0x00000000;
+       rmesa->hw.shade.cmd[4] = 0x00000000;
 }
 
 static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
@@ -1526,30 +1567,31 @@ static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
 
        for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_MAX; i++) {
                if (rmesa->state.sw_tcl_inputs[i] != -1) {
-                       prog->program.body.i[program_end].op = EASY_VSF_OP(MUL, o_reg++, ALL, RESULT);
-                       prog->program.body.i[program_end].src[0] = VSF_REG(rmesa->state.sw_tcl_inputs[i]);
-                       prog->program.body.i[program_end].src[1] = VSF_ATTR_UNITY(rmesa->state.sw_tcl_inputs[i]);
-                       prog->program.body.i[program_end].src[2] = VSF_UNITY(rmesa->state.sw_tcl_inputs[i]);
-                       program_end++;
+                       prog->program.body.i[program_end + 0] = EASY_VSF_OP(MUL, o_reg++, ALL, RESULT);
+                       prog->program.body.i[program_end + 1] = VSF_REG(rmesa->state.sw_tcl_inputs[i]);
+                       prog->program.body.i[program_end + 2] = VSF_ATTR_UNITY(rmesa->state.sw_tcl_inputs[i]);
+                       prog->program.body.i[program_end + 3] = VSF_UNITY(rmesa->state.sw_tcl_inputs[i]);
+                       program_end += 4;
                }
        }
 
-       prog->program.length = program_end * 4;
+       prog->program.length = program_end;
 
-       r300SetupVertexProgramFragment(rmesa, VSF_DEST_PROGRAM, &(prog->program));
+       r300SetupVertexProgramFragment(rmesa, R300_PVS_UPLOAD_PROGRAM,
+                                      &(prog->program));
        inst_count = (prog->program.length / 4) - 1;
 
        R300_STATECHANGE(rmesa, pvs);
        rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
-         (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
-         (inst_count << R300_PVS_CNTL_1_POS_END_SHIFT) |
-         (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
+           (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
+           (inst_count << R300_PVS_CNTL_1_POS_END_SHIFT) |
+           (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
        rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] =
-         (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) |
-         (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
+           (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) |
+           (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
        rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =
-         (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) |
-         (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT);
+           (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) |
+           (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT);
 }
 
 static void r300SetupRealVertexProgram(r300ContextPtr rmesa)
@@ -1570,7 +1612,7 @@ static void r300SetupRealVertexProgram(r300ContextPtr rmesa)
        bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
        param_count /= 4;
 
-       r300SetupVertexProgramFragment(rmesa, VSF_DEST_PROGRAM, &(prog->program));
+       r300SetupVertexProgramFragment(rmesa, R300_PVS_UPLOAD_PROGRAM, &(prog->program));
        inst_count = (prog->program.length / 4) - 1;
 
        R300_STATECHANGE(rmesa, pvs);
@@ -1848,15 +1890,10 @@ static void r300ResetHwState(r300ContextPtr r300)
        r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
        r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0);
 
-       r300->hw.shade.cmd[1] = 0x00000002;
        r300ShadeModel(ctx, ctx->Light.ShadeModel);
-       r300->hw.shade.cmd[3] = 0x00000000;
-       r300->hw.shade.cmd[4] = 0x00000000;
 
        r300PolygonMode(ctx, GL_FRONT, ctx->Polygon.FrontMode);
        r300PolygonMode(ctx, GL_BACK, ctx->Polygon.BackMode);
-       r300->hw.polygon_mode.cmd[2] = 0x00000001;
-       r300->hw.polygon_mode.cmd[3] = 0x00000000;
        r300->hw.zbias_cntl.cmd[1] = 0x00000000;
 
        r300PolygonOffset(ctx, ctx->Polygon.OffsetFactor,
@@ -1887,14 +1924,11 @@ static void r300ResetHwState(r300ContextPtr r300)
        r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
        r300Fogfv(ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL);
 
-       r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
        r300->hw.unk4BD8.cmd[1] = 0;
 
        r300->hw.unk4E00.cmd[1] = 0;
 
        r300BlendColor(ctx, ctx->Color.BlendColor);
-       r300->hw.blend_color.cmd[2] = 0;
-       r300->hw.blend_color.cmd[3] = 0;
 
        /* Again, r300ClearBuffer uses this */
        r300->hw.cb.cmd[R300_CB_OFFSET] =
@@ -1925,25 +1959,6 @@ static void r300ResetHwState(r300ContextPtr r300)
        r300->hw.unk4EA0.cmd[1] = 0x00000000;
        r300->hw.unk4EA0.cmd[2] = 0xffffffff;
 
-       switch (ctx->Visual.depthBits) {
-       case 16:
-               r300->hw.zstencil_format.cmd[1] = R300_DEPTH_FORMAT_16BIT_INT_Z;
-               break;
-       case 24:
-               r300->hw.zstencil_format.cmd[1] = R300_DEPTH_FORMAT_24BIT_INT_Z;
-               break;
-       default:
-               fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
-                       ctx->Visual.depthBits);
-               _mesa_exit(-1);
-
-       }
-       /* z compress? */
-       //r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
-
-       r300->hw.zstencil_format.cmd[3] = 0x00000003;
-       r300->hw.zstencil_format.cmd[4] = 0x00000000;
-
        r300->hw.zb.cmd[R300_ZB_OFFSET] =
            r300->radeon.radeonScreen->depthOffset +
            r300->radeon.radeonScreen->fbLocation;
index 16dddf6557d5317ed539a9f17ed244cb4070d688..7d4e8c95112b1e0ce5410f139cbaafb37ed51923 100644 (file)
@@ -29,6 +29,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  * \file
  *
  * \author Aapo Tahkola <aet@rasterburn.org>
+ *
+ * \author Oliver McFadden <z3ro.geek@gmail.com>
+ *
+ * For a description of the vertex program instruction set see r300_reg.h.
  */
 
 #include "glheader.h"
@@ -55,54 +59,58 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #error Cannot change these!
 #endif
 
-#define SCALAR_FLAG (1<<31)
-#define FLAG_MASK (1<<31)
-#define OP_MASK        (0xf)           /* we are unlikely to have more than 15 */
-#define OPN(operator, ip) {#operator, OPCODE_##operator, ip}
-
-static struct {
-       char *name;
-       int opcode;
-       unsigned long ip;       /* number of input operands and flags */
-} op_names[] = {
-       /* *INDENT-OFF* */
-       OPN(ABS, 1),
-       OPN(ADD, 2),
-       OPN(ARL, 1 | SCALAR_FLAG),
-       OPN(DP3, 2),
-       OPN(DP4, 2),
-       OPN(DPH, 2),
-       OPN(DST, 2),
-       OPN(EX2, 1 | SCALAR_FLAG),
-       OPN(EXP, 1 | SCALAR_FLAG),
-       OPN(FLR, 1),
-       OPN(FRC, 1),
-       OPN(LG2, 1 | SCALAR_FLAG),
-       OPN(LIT, 1),
-       OPN(LOG, 1 | SCALAR_FLAG),
-       OPN(MAD, 3),
-       OPN(MAX, 2),
-       OPN(MIN, 2),
-       OPN(MOV, 1),
-       OPN(MUL, 2),
-       OPN(POW, 2 | SCALAR_FLAG),
-       OPN(RCP, 1 | SCALAR_FLAG),
-       OPN(RSQ, 1 | SCALAR_FLAG),
-       OPN(SGE, 2),
-       OPN(SLT, 2),
-       OPN(SUB, 2),
-       OPN(SWZ, 1),
-       OPN(XPD, 2),
-       OPN(RCC, 0),    //extra
-       OPN(PRINT, 0),
-       OPN(END, 0)
-       /* *INDENT-ON* */
-};
-
-#undef OPN
+/* TODO: Get rid of t_src_class call */
+#define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \
+                      ((t_src_class(a.File) == VSF_IN_CLASS_PARAM && \
+                        t_src_class(b.File) == VSF_IN_CLASS_PARAM) || \
+                       (t_src_class(a.File) == VSF_IN_CLASS_ATTR && \
+                        t_src_class(b.File) == VSF_IN_CLASS_ATTR)))) \
+
+#define ZERO_SRC_0 (MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), \
+                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
+                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
+                                   t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4))
+
+#define ZERO_SRC_1 (MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), \
+                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
+                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
+                                   t_src_class(src[1].File), VSF_FLAG_NONE) | (src[1].RelAddr << 4))
+
+#define ZERO_SRC_2 (MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), \
+                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
+                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
+                                   t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4))
+
+#define ONE_SRC_0 (MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), \
+                                   SWIZZLE_ONE, SWIZZLE_ONE, \
+                                   SWIZZLE_ONE, SWIZZLE_ONE, \
+                                   t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4))
+
+#define ONE_SRC_1 (MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), \
+                                   SWIZZLE_ONE, SWIZZLE_ONE, \
+                                   SWIZZLE_ONE, SWIZZLE_ONE, \
+                                   t_src_class(src[1].File), VSF_FLAG_NONE) | (src[1].RelAddr << 4))
+
+#define ONE_SRC_2 (MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), \
+                                   SWIZZLE_ONE, SWIZZLE_ONE, \
+                                   SWIZZLE_ONE, SWIZZLE_ONE, \
+                                   t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4))
+
+/* DP4 version seems to trigger some hw peculiarity */
+//#define PREFER_DP4
+
+#define FREE_TEMPS() \
+       do { \
+               if(u_temp_i < vp->num_temporaries) { \
+                       WARN_ONCE("Ran out of temps, num temps %d, us %d\n", vp->num_temporaries, u_temp_i); \
+                       vp->native = GL_FALSE; \
+               } \
+               u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \
+       } while (0)
 
 int r300VertexProgUpdateParams(GLcontext * ctx,
-                              struct r300_vertex_program_cont *vp, float *dst)
+                              struct r300_vertex_program_cont *vp,
+                              float *dst)
 {
        int pi;
        struct gl_vertex_program *mesa_vp = &vp->mesa_program;
@@ -234,8 +242,8 @@ static void vp_dump_inputs(struct r300_vertex_program *vp, char *caller)
        int i;
 
        if (vp == NULL) {
-               fprintf(stderr, "vp null in call to %s from %s\n", __FUNCTION__,
-                       caller);
+               fprintf(stderr, "vp null in call to %s from %s\n",
+                       __FUNCTION__, caller);
                return;
        }
 
@@ -276,6 +284,8 @@ static unsigned long t_src_index(struct r300_vertex_program *vp,
        }
 }
 
+/* these two functions should probably be merged... */
+
 static unsigned long t_src(struct r300_vertex_program *vp,
                           struct prog_src_register *src)
 {
@@ -294,7 +304,9 @@ static unsigned long t_src(struct r300_vertex_program *vp,
 static unsigned long t_src_scalar(struct r300_vertex_program *vp,
                                  struct prog_src_register *src)
 {
-
+       /* src->NegateBase uses the NEGATE_ flags from program_instruction.h,
+        * which equal our VSF_FLAGS_ values, so it's safe to just pass it here.
+        */
        return MAKE_VSF_SOURCE(t_src_index(vp, src),
                               t_swizzle(GET_SWZ(src->Swizzle, 0)),
                               t_swizzle(GET_SWZ(src->Swizzle, 0)),
@@ -306,128 +318,741 @@ static unsigned long t_src_scalar(struct r300_vertex_program *vp,
            (src->RelAddr << 4);
 }
 
-static unsigned long t_opcode(enum prog_opcode opcode)
+static GLboolean valid_dst(struct r300_vertex_program *vp,
+                          struct prog_dst_register *dst)
 {
+       if (dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1) {
+               return GL_FALSE;
+       } else if (dst->File == PROGRAM_ADDRESS) {
+               assert(dst->Index == 0);
+       }
 
-       switch (opcode) {
-       /* *INDENT-OFF* */
-       case OPCODE_ARL: return R300_VPI_OUT_OP_ARL;
-       case OPCODE_DST: return R300_VPI_OUT_OP_DST;
-       case OPCODE_EX2: return R300_VPI_OUT_OP_EX2;
-       case OPCODE_EXP: return R300_VPI_OUT_OP_EXP;
-       case OPCODE_FRC: return R300_VPI_OUT_OP_FRC;
-       case OPCODE_LG2: return R300_VPI_OUT_OP_LG2;
-       case OPCODE_LOG: return R300_VPI_OUT_OP_LOG;
-       case OPCODE_MAX: return R300_VPI_OUT_OP_MAX;
-       case OPCODE_MIN: return R300_VPI_OUT_OP_MIN;
-       case OPCODE_MUL: return R300_VPI_OUT_OP_MUL;
-       case OPCODE_RCP: return R300_VPI_OUT_OP_RCP;
-       case OPCODE_RSQ: return R300_VPI_OUT_OP_RSQ;
-       case OPCODE_SGE: return R300_VPI_OUT_OP_SGE;
-       case OPCODE_SLT: return R300_VPI_OUT_OP_SLT;
-       case OPCODE_DP4: return R300_VPI_OUT_OP_DOT;
-       /* *INDENT-ON* */
+       return GL_TRUE;
+}
 
-       default:
-               fprintf(stderr, "%s: Should not be called with opcode %d!",
-                       __FUNCTION__, opcode);
-       }
-       _mesa_exit(-1);
-       return 0;
+/*
+ * Instruction    Inputs  Output   Description
+ * -----------    ------  ------   --------------------------------
+ * ABS            v       v        absolute value
+ * ADD            v,v     v        add
+ * ARL            s       a        address register load
+ * DP3            v,v     ssss     3-component dot product
+ * DP4            v,v     ssss     4-component dot product
+ * DPH            v,v     ssss     homogeneous dot product
+ * DST            v,v     v        distance vector
+ * EX2            s       ssss     exponential base 2
+ * EXP            s       v        exponential base 2 (approximate)
+ * FLR            v       v        floor
+ * FRC            v       v        fraction
+ * LG2            s       ssss     logarithm base 2
+ * LIT            v       v        compute light coefficients
+ * LOG            s       v        logarithm base 2 (approximate)
+ * MAD            v,v,v   v        multiply and add
+ * MAX            v,v     v        maximum
+ * MIN            v,v     v        minimum
+ * MOV            v       v        move
+ * MUL            v,v     v        multiply
+ * POW            s,s     ssss     exponentiate
+ * RCP            s       ssss     reciprocal
+ * RSQ            s       ssss     reciprocal square root
+ * SGE            v,v     v        set on greater than or equal
+ * SLT            v,v     v        set on less than
+ * SUB            v,v     v        subtract
+ * SWZ            v       v        extended swizzle
+ * XPD            v,v     v        cross product
+ *
+ * Table X.5:  Summary of vertex program instructions.  "v" indicates a
+ * floating-point vector input or output, "s" indicates a floating-point
+ * scalar input, "ssss" indicates a scalar output replicated across a
+ * 4-component result vector, and "a" indicates a single address register
+ * component.
+ */
+
+static GLuint *t_opcode_abs(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       //MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
+
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_MAX, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] =
+           MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 3)),
+                           t_src_class(src[0].File),
+                           (!src[0].
+                            NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
+           (src[0].RelAddr << 4);
+       inst[3] = 0;
+
+       return inst;
 }
 
-static unsigned long op_operands(enum prog_opcode opcode)
+static GLuint *t_opcode_add(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
 {
-       int i;
+       unsigned long hw_op;
 
-       /* Can we trust mesas opcodes to be in order ? */
-       for (i = 0; i < sizeof(op_names) / sizeof(*op_names); i++)
-               if (op_names[i].opcode == opcode)
-                       return op_names[i].ip;
+#if 1
+       hw_op = (src[0].File == PROGRAM_TEMPORARY
+                && src[1].File ==
+                PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+           R300_VPI_OUT_OP_MAD;
+
+       inst[0] =
+           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       inst[1] = ONE_SRC_0;
+       inst[2] = t_src(vp, &src[0]);
+       inst[3] = t_src(vp, &src[1]);
+#else
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = t_src(vp, &src[1]);
+       inst[3] = ZERO_SRC_1;
 
-       fprintf(stderr, "op %d not found in op_names\n", opcode);
-       _mesa_exit(-1);
-       return 0;
+#endif
+
+       return inst;
 }
 
-static GLboolean valid_dst(struct r300_vertex_program *vp,
-                          struct prog_dst_register *dst)
+static GLuint *t_opcode_arl(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
 {
-       if (dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1) {
-               return GL_FALSE;
-       } else if (dst->File == PROGRAM_ADDRESS) {
-               assert(dst->Index == 0);
-       }
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_ARL, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
 
-       return GL_TRUE;
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+
+       return inst;
 }
 
-/* TODO: Get rid of t_src_class call */
-#define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \
-                      ((t_src_class(a.File) == VSF_IN_CLASS_PARAM && \
-                        t_src_class(b.File) == VSF_IN_CLASS_PARAM) || \
-                       (t_src_class(a.File) == VSF_IN_CLASS_ATTR && \
-                        t_src_class(b.File) == VSF_IN_CLASS_ATTR)))) \
+static GLuint *t_opcode_dp3(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO}
+
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] =
+           MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
+                           SWIZZLE_ZERO, t_src_class(src[0].File),
+                           src[0].
+                           NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |
+           (src[0].RelAddr << 4);
+
+       inst[2] =
+           MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
+                           SWIZZLE_ZERO, t_src_class(src[1].File),
+                           src[1].
+                           NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |
+           (src[1].RelAddr << 4);
+
+       inst[3] = ZERO_SRC_1;
+
+       return inst;
+}
 
-#define ZERO_SRC_0 (MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), \
-                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
-                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
-                                   t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4))
+static GLuint *t_opcode_dp4(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
 
-#define ZERO_SRC_1 (MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), \
-                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
-                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
-                                   t_src_class(src[1].File), VSF_FLAG_NONE) | (src[1].RelAddr << 4))
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = t_src(vp, &src[1]);
+       inst[3] = ZERO_SRC_1;
 
-#define ZERO_SRC_2 (MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), \
-                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
-                                   SWIZZLE_ZERO, SWIZZLE_ZERO, \
-                                   t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4))
+       return inst;
+}
 
-#define ONE_SRC_0 (MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), \
-                                   SWIZZLE_ONE, SWIZZLE_ONE, \
-                                   SWIZZLE_ONE, SWIZZLE_ONE, \
-                                   t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4))
+static GLuint *t_opcode_dph(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W}
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] =
+           MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
+                           VSF_IN_COMPONENT_ONE, t_src_class(src[0].File),
+                           src[0].
+                           NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |
+           (src[0].RelAddr << 4);
+       inst[2] = t_src(vp, &src[1]);
+       inst[3] = ZERO_SRC_1;
+
+       return inst;
+}
 
-#define ONE_SRC_1 (MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), \
-                                   SWIZZLE_ONE, SWIZZLE_ONE, \
-                                   SWIZZLE_ONE, SWIZZLE_ONE, \
-                                   t_src_class(src[1].File), VSF_FLAG_NONE) | (src[1].RelAddr << 4))
+static GLuint *t_opcode_dst(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_DST, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
 
-#define ONE_SRC_2 (MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), \
-                                   SWIZZLE_ONE, SWIZZLE_ONE, \
-                                   SWIZZLE_ONE, SWIZZLE_ONE, \
-                                   t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4))
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = t_src(vp, &src[1]);
+       inst[3] = ZERO_SRC_1;
 
-/* DP4 version seems to trigger some hw peculiarity */
-//#define PREFER_DP4
+       return inst;
+}
 
-#define FREE_TEMPS() \
-       do { \
-               if(u_temp_i < vp->num_temporaries) { \
-                       WARN_ONCE("Ran out of temps, num temps %d, us %d\n", vp->num_temporaries, u_temp_i); \
-                       vp->native = GL_FALSE; \
-               } \
-               u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \
-       } while (0)
+static GLuint *t_opcode_ex2(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_EX2, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
 
-static void r300TranslateVertexShader(struct r300_vertex_program *vp,
-                                     struct prog_instruction *vpi)
+       inst[1] = t_src_scalar(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+
+       return inst;
+}
+
+static GLuint *t_opcode_exp(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_EXP, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src_scalar(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+
+       return inst;
+}
+
+static GLuint *t_opcode_flr(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3], int *u_temp_i)
+{
+       /* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W}
+          ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} TMP 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W */
+
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_FRC, *u_temp_i,
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       VSF_OUT_CLASS_TMP);
+
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+       inst += 4;
+
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] =
+           MAKE_VSF_SOURCE(*u_temp_i, VSF_IN_COMPONENT_X,
+                           VSF_IN_COMPONENT_Y, VSF_IN_COMPONENT_Z,
+                           VSF_IN_COMPONENT_W, VSF_IN_CLASS_TMP,
+                           /* Not 100% sure about this */
+                           (!src[0].
+                            NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE
+                           /*VSF_FLAG_ALL */ );
+
+       inst[3] = ZERO_SRC_0;
+       (*u_temp_i)--;
+
+       return inst;
+}
+
+static GLuint *t_opcode_frc(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_FRC, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+
+       return inst;
+}
+
+static GLuint *t_opcode_lg2(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       // LG2 RESULT 1.X Y Z W PARAM 0{} {X X X X}
+
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_LG2, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] =
+           MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
+                           t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
+                           t_src_class(src[0].File),
+                           src[0].
+                           NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
+           (src[0].RelAddr << 4);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+
+       return inst;
+}
+
+static GLuint *t_opcode_lit(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       //LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W}
+
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_LIT, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       /* NOTE: Users swizzling might not work. */
+       inst[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 0)),      // x
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 3)),        // w
+                                 VSF_IN_COMPONENT_ZERO,        // z
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 1)),        // y
+                                 t_src_class(src[0].File),
+                                 src[0].
+                                 NegateBase ? VSF_FLAG_ALL :
+                                 VSF_FLAG_NONE) | (src[0].RelAddr << 4);
+       inst[2] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)),      // y
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 3)),        // w
+                                 VSF_IN_COMPONENT_ZERO,        // z
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 0)),        // x
+                                 t_src_class(src[0].File),
+                                 src[0].
+                                 NegateBase ? VSF_FLAG_ALL :
+                                 VSF_FLAG_NONE) | (src[0].RelAddr << 4);
+       inst[3] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)),      // y
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 0)),        // x
+                                 VSF_IN_COMPONENT_ZERO,        // z
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 3)),        // w
+                                 t_src_class(src[0].File),
+                                 src[0].
+                                 NegateBase ? VSF_FLAG_ALL :
+                                 VSF_FLAG_NONE) | (src[0].RelAddr << 4);
+
+       return inst;
+}
+
+static GLuint *t_opcode_log(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_LOG, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src_scalar(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+
+       return inst;
+}
+
+static GLuint *t_opcode_mad(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
 {
-       int i, cur_reg = 0;
-       VERTEX_SHADER_INSTRUCTION *o_inst;
-       unsigned long operands;
-       int are_srcs_scalar;
        unsigned long hw_op;
-       /* Initial value should be last tmp reg that hw supports.
-          Strangely enough r300 doesnt mind even though these would be out of range.
-          Smart enough to realize that it doesnt need it? */
-       int u_temp_i = VSF_MAX_FRAGMENT_TEMPS - 1;
-       struct prog_src_register src[3];
 
-       vp->pos_end = 0;        /* Not supported yet */
-       vp->program.length = 0;
-       /*vp->num_temporaries=mesa_vp->Base.NumTemporaries; */
+       hw_op = (src[0].File == PROGRAM_TEMPORARY
+                && src[1].File == PROGRAM_TEMPORARY
+                && src[2].File ==
+                PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+           R300_VPI_OUT_OP_MAD;
+
+       inst[0] =
+           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = t_src(vp, &src[1]);
+       inst[3] = t_src(vp, &src[2]);
+
+       return inst;
+}
+
+static GLuint *t_opcode_max(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_MAX, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = t_src(vp, &src[1]);
+       inst[3] = ZERO_SRC_1;
+
+       return inst;
+}
+
+static GLuint *t_opcode_min(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_MIN, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = t_src(vp, &src[1]);
+       inst[3] = ZERO_SRC_1;
+
+       return inst;
+}
+
+static GLuint *t_opcode_mov(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
+
+#if 1
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+#else
+       hw_op =
+           (src[0].File ==
+            PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+           R300_VPI_OUT_OP_MAD;
+
+       inst[0] =
+           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = ONE_SRC_0;
+       inst[3] = ZERO_SRC_0;
+#endif
+
+       return inst;
+}
+
+static GLuint *t_opcode_mul(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       unsigned long hw_op;
+
+       // HW mul can take third arg but appears to have some other limitations.
+
+       hw_op = (src[0].File == PROGRAM_TEMPORARY
+                && src[1].File ==
+                PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+           R300_VPI_OUT_OP_MAD;
+
+       inst[0] =
+           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = t_src(vp, &src[1]);
+
+       inst[3] = ZERO_SRC_1;
+
+       return inst;
+}
+
+static GLuint *t_opcode_pow(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_POW, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       inst[1] = t_src_scalar(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = t_src_scalar(vp, &src[1]);
+
+       return inst;
+}
+
+static GLuint *t_opcode_rcp(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_RCP, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src_scalar(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+
+       return inst;
+}
+
+static GLuint *t_opcode_rsq(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_RSQ, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src_scalar(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+
+       return inst;
+}
+
+static GLuint *t_opcode_sge(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_SGE, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = t_src(vp, &src[1]);
+       inst[3] = ZERO_SRC_1;
+
+       return inst;
+}
+
+static GLuint *t_opcode_slt(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_SLT, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = t_src(vp, &src[1]);
+       inst[3] = ZERO_SRC_1;
+
+       return inst;
+}
+
+static GLuint *t_opcode_sub(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       unsigned long hw_op;
+
+       //ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
+
+#if 1
+       hw_op = (src[0].File == PROGRAM_TEMPORARY
+                && src[1].File ==
+                PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+           R300_VPI_OUT_OP_MAD;
+
+       inst[0] =
+           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = ONE_SRC_0;
+       inst[3] =
+           MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 3)),
+                           t_src_class(src[1].File),
+                           (!src[1].
+                            NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
+           (src[1].RelAddr << 4);
+#else
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] =
+           MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
+                           t_swizzle(GET_SWZ(src[1].Swizzle, 3)),
+                           t_src_class(src[1].File),
+                           (!src[1].
+                            NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
+           (src[1].RelAddr << 4);
+       inst[3] = 0;
+#endif
+
+       return inst;
+}
+
+static GLuint *t_opcode_swz(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3])
+{
+       //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
+
+#if 1
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = ZERO_SRC_0;
+       inst[3] = ZERO_SRC_0;
+#else
+       hw_op =
+           (src[0].File ==
+            PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+           R300_VPI_OUT_OP_MAD;
+
+       inst[0] =
+           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+       inst[1] = t_src(vp, &src[0]);
+       inst[2] = ONE_SRC_0;
+       inst[3] = ZERO_SRC_0;
+#endif
+
+       return inst;
+}
+
+static GLuint *t_opcode_xpd(struct r300_vertex_program *vp,
+                           struct prog_instruction *vpi, GLuint * inst,
+                           struct prog_src_register src[3], int *u_temp_i)
+{
+       /* mul r0, r1.yzxw, r2.zxyw
+          mad r0, -r2.yzxw, r1.zxyw, r0
+          NOTE: might need MAD_2
+        */
+
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_MAD, *u_temp_i,
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       VSF_OUT_CLASS_TMP);
+
+       inst[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)),      // y
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 2)),        // z
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 0)),        // x
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 3)),        // w
+                                 t_src_class(src[0].File),
+                                 src[0].
+                                 NegateBase ? VSF_FLAG_ALL :
+                                 VSF_FLAG_NONE) | (src[0].RelAddr << 4);
+
+       inst[2] = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 2)),      // z
+                                 t_swizzle(GET_SWZ(src[1].Swizzle, 0)),        // x
+                                 t_swizzle(GET_SWZ(src[1].Swizzle, 1)),        // y
+                                 t_swizzle(GET_SWZ(src[1].Swizzle, 3)),        // w
+                                 t_src_class(src[1].File),
+                                 src[1].
+                                 NegateBase ? VSF_FLAG_ALL :
+                                 VSF_FLAG_NONE) | (src[1].RelAddr << 4);
+
+       inst[3] = ZERO_SRC_1;
+       inst += 4;
+       (*u_temp_i)--;
+
+       inst[0] =
+           MAKE_VSF_OP(R300_VPI_OUT_OP_MAD, t_dst_index(vp, &vpi->DstReg),
+                       t_dst_mask(vpi->DstReg.WriteMask),
+                       t_dst_class(vpi->DstReg.File));
+
+       inst[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 1)),      // y
+                                 t_swizzle(GET_SWZ(src[1].Swizzle, 2)),        // z
+                                 t_swizzle(GET_SWZ(src[1].Swizzle, 0)),        // x
+                                 t_swizzle(GET_SWZ(src[1].Swizzle, 3)),        // w
+                                 t_src_class(src[1].File),
+                                 (!src[1].
+                                  NegateBase) ? VSF_FLAG_ALL :
+                                 VSF_FLAG_NONE) | (src[1].RelAddr << 4);
+
+       inst[2] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 2)),      // z
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 0)),        // x
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 1)),        // y
+                                 t_swizzle(GET_SWZ(src[0].Swizzle, 3)),        // w
+                                 t_src_class(src[0].File),
+                                 src[0].
+                                 NegateBase ? VSF_FLAG_ALL :
+                                 VSF_FLAG_NONE) | (src[0].RelAddr << 4);
+
+       inst[3] =
+           MAKE_VSF_SOURCE(*u_temp_i + 1, VSF_IN_COMPONENT_X,
+                           VSF_IN_COMPONENT_Y, VSF_IN_COMPONENT_Z,
+                           VSF_IN_COMPONENT_W, VSF_IN_CLASS_TMP,
+                           VSF_FLAG_NONE);
+
+       return inst;
+}
+
+static void t_inputs_outputs(struct r300_vertex_program *vp)
+{
+       int i;
+       int cur_reg = 0;
 
        for (i = 0; i < VERT_ATTRIB_MAX; i++)
                vp->inputs[i] = -1;
@@ -437,39 +1062,71 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp,
 
        assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS));
 
-       /* Assign outputs */
-       if (vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS))
+       if (vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)) {
                vp->outputs[VERT_RESULT_HPOS] = cur_reg++;
+       }
 
-       if (vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ))
+       if (vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ)) {
                vp->outputs[VERT_RESULT_PSIZ] = cur_reg++;
+       }
 
-       if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL0))
+       if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL0)) {
                vp->outputs[VERT_RESULT_COL0] = cur_reg++;
+       }
 
-       if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL1))
-               vp->outputs[VERT_RESULT_COL1] = cur_reg++;
-
-#if 0                          /* Not supported yet */
-       if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0))
-               vp->outputs[VERT_RESULT_BFC0] = cur_reg++;
+       if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL1)) {
+               vp->outputs[VERT_RESULT_COL1] =
+                   vp->outputs[VERT_RESULT_COL0] + 1;
+               cur_reg = vp->outputs[VERT_RESULT_COL1] + 1;
+       }
 
-       if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1))
-               vp->outputs[VERT_RESULT_BFC1] = cur_reg++;
+       if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) {
+               vp->outputs[VERT_RESULT_BFC0] =
+                   vp->outputs[VERT_RESULT_COL0] + 2;
+               cur_reg = vp->outputs[VERT_RESULT_BFC0] + 2;
+       }
 
-       if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC))
+       if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) {
+               vp->outputs[VERT_RESULT_BFC1] =
+                   vp->outputs[VERT_RESULT_COL0] + 3;
+               cur_reg = vp->outputs[VERT_RESULT_BFC1] + 1;
+       }
+#if 0
+       if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) {
                vp->outputs[VERT_RESULT_FOGC] = cur_reg++;
+       }
 #endif
 
-       for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++)
-               if (vp->key.OutputsWritten & (1 << i))
+       for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) {
+               if (vp->key.OutputsWritten & (1 << i)) {
                        vp->outputs[i] = cur_reg++;
+               }
+       }
+}
+
+static void r300TranslateVertexShader(struct r300_vertex_program *vp,
+                                     struct prog_instruction *vpi)
+{
+       int i;
+       GLuint *inst;
+       unsigned long num_operands;
+       /* Initial value should be last tmp reg that hw supports.
+          Strangely enough r300 doesnt mind even though these would be out of range.
+          Smart enough to realize that it doesnt need it? */
+       int u_temp_i = VSF_MAX_FRAGMENT_TEMPS - 1;
+       struct prog_src_register src[3];
 
+       vp->pos_end = 0;        /* Not supported yet */
+       vp->program.length = 0;
+       /*vp->num_temporaries=mesa_vp->Base.NumTemporaries; */
        vp->translated = GL_TRUE;
        vp->native = GL_TRUE;
 
-       o_inst = vp->program.body.i;
-       for (; vpi->Opcode != OPCODE_END; vpi++, o_inst++) {
+       t_inputs_outputs(vp);
+
+       for (inst = vp->program.body.i; vpi->Opcode != OPCODE_END;
+            vpi++, inst += 4) {
+
                FREE_TEMPS();
 
                if (!valid_dst(vp, &vpi->DstReg)) {
@@ -478,61 +1135,62 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp,
                        vpi->DstReg.Index = u_temp_i;
                }
 
-               operands = op_operands(vpi->Opcode);
-               are_srcs_scalar = operands & SCALAR_FLAG;
-               operands &= OP_MASK;
+               num_operands = _mesa_num_inst_src_regs(vpi->Opcode);
 
-               for (i = 0; i < operands; i++)
+               /* copy the sources (src) from mesa into a local variable... is this needed? */
+               for (i = 0; i < num_operands; i++) {
                        src[i] = vpi->SrcReg[i];
+               }
 
-               if (operands == 3) {    /* TODO: scalars */
+               if (num_operands == 3) {        /* TODO: scalars */
                        if (CMP_SRCS(src[1], src[2])
                            || CMP_SRCS(src[0], src[2])) {
-                               o_inst->op =
-                                   MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, u_temp_i,
-                                               VSF_FLAG_ALL,
+                               inst[0] =
+                                   MAKE_VSF_OP(R300_VPI_OUT_OP_ADD,
+                                               u_temp_i, VSF_FLAG_ALL,
                                                VSF_OUT_CLASS_TMP);
 
-                               o_inst->src[0] =
-                                   MAKE_VSF_SOURCE(t_src_index(vp, &src[2]),
+                               inst[1] =
+                                   MAKE_VSF_SOURCE(t_src_index
+                                                   (vp, &src[2]),
                                                    SWIZZLE_X, SWIZZLE_Y,
                                                    SWIZZLE_Z, SWIZZLE_W,
-                                                   t_src_class(src[2].File),
-                                                   VSF_FLAG_NONE) | (src[2].
-                                                                     RelAddr <<
-                                                                     4);
+                                                   t_src_class(src[2].
+                                                               File),
+                                                   VSF_FLAG_NONE) |
+                                   (src[2].RelAddr << 4);
 
-                               o_inst->src[1] = ZERO_SRC_2;
-                               o_inst->src[2] = ZERO_SRC_2;
-                               o_inst++;
+                               inst[2] = ZERO_SRC_2;
+                               inst[3] = ZERO_SRC_2;
+                               inst += 4;
 
                                src[2].File = PROGRAM_TEMPORARY;
                                src[2].Index = u_temp_i;
                                src[2].RelAddr = 0;
                                u_temp_i--;
                        }
-
                }
 
-               if (operands >= 2) {
+               if (num_operands >= 2) {
                        if (CMP_SRCS(src[1], src[0])) {
-                               o_inst->op =
-                                   MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, u_temp_i,
-                                               VSF_FLAG_ALL,
+                               inst[0] =
+                                   MAKE_VSF_OP(R300_VPI_OUT_OP_ADD,
+                                               u_temp_i, VSF_FLAG_ALL,
                                                VSF_OUT_CLASS_TMP);
 
-                               o_inst->src[0] =
-                                   MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+                               inst[1] =
+                                   MAKE_VSF_SOURCE(t_src_index
+                                                   (vp, &src[0]),
                                                    SWIZZLE_X, SWIZZLE_Y,
                                                    SWIZZLE_Z, SWIZZLE_W,
-                                                   t_src_class(src[0].File),
-                                                   VSF_FLAG_NONE) | (src[0].
-                                                                     RelAddr <<
-                                                                     4);
+                                                   t_src_class(src[0].
+                                                               File),
+                                                   VSF_FLAG_NONE) |
+                                   (src[0].RelAddr << 4);
 
-                               o_inst->src[1] = ZERO_SRC_0;
-                               o_inst->src[2] = ZERO_SRC_0;
-                               o_inst++;
+                               inst[2] = ZERO_SRC_0;
+                               inst[3] = ZERO_SRC_0;
+                               inst += 4;
 
                                src[0].File = PROGRAM_TEMPORARY;
                                src[0].Index = u_temp_i;
@@ -541,517 +1199,103 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp,
                        }
                }
 
-               /* These ops need special handling. */
                switch (vpi->Opcode) {
-               case OPCODE_POW:
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_POW,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-                       o_inst->src[0] = t_src_scalar(vp, &src[0]);
-                       o_inst->src[1] = ZERO_SRC_0;
-                       o_inst->src[2] = t_src_scalar(vp, &src[1]);
-                       goto next;
-
-               case OPCODE_MOV:        //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
-               case OPCODE_SWZ:
-#if 1
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_ADD,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-                       o_inst->src[0] = t_src(vp, &src[0]);
-                       o_inst->src[1] = ZERO_SRC_0;
-                       o_inst->src[2] = ZERO_SRC_0;
-#else
-                       hw_op =
-                           (src[0].File ==
-                            PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
-                           R300_VPI_OUT_OP_MAD;
-
-                       o_inst->op =
-                           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-                       o_inst->src[0] = t_src(vp, &src[0]);
-                       o_inst->src[1] = ONE_SRC_0;
-                       o_inst->src[2] = ZERO_SRC_0;
-#endif
-
-                       goto next;
-
+               case OPCODE_ABS:
+                       inst = t_opcode_abs(vp, vpi, inst, src);
+                       break;
                case OPCODE_ADD:
-#if 1
-                       hw_op = (src[0].File == PROGRAM_TEMPORARY &&
-                                src[1].File ==
-                                PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
-                           R300_VPI_OUT_OP_MAD;
-
-                       o_inst->op =
-                           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-                       o_inst->src[0] = ONE_SRC_0;
-                       o_inst->src[1] = t_src(vp, &src[0]);
-                       o_inst->src[2] = t_src(vp, &src[1]);
-#else
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_ADD,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-                       o_inst->src[0] = t_src(vp, &src[0]);
-                       o_inst->src[1] = t_src(vp, &src[1]);
-                       o_inst->src[2] = ZERO_SRC_1;
-
-#endif
-                       goto next;
-
-               case OPCODE_MAD:
-                       hw_op = (src[0].File == PROGRAM_TEMPORARY &&
-                                src[1].File == PROGRAM_TEMPORARY &&
-                                src[2].File ==
-                                PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
-                           R300_VPI_OUT_OP_MAD;
-
-                       o_inst->op =
-                           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-                       o_inst->src[0] = t_src(vp, &src[0]);
-                       o_inst->src[1] = t_src(vp, &src[1]);
-                       o_inst->src[2] = t_src(vp, &src[2]);
-                       goto next;
-
-               case OPCODE_MUL:        /* HW mul can take third arg but appears to have some other limitations. */
-                       hw_op = (src[0].File == PROGRAM_TEMPORARY &&
-                                src[1].File ==
-                                PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
-                           R300_VPI_OUT_OP_MAD;
-
-                       o_inst->op =
-                           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-                       o_inst->src[0] = t_src(vp, &src[0]);
-                       o_inst->src[1] = t_src(vp, &src[1]);
-
-                       o_inst->src[2] = ZERO_SRC_1;
-                       goto next;
-
-               case OPCODE_DP3:        //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO}
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_DOT,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-
-                       o_inst->src[0] =
-                           MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 0)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 1)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 2)),
-                                           SWIZZLE_ZERO,
-                                           t_src_class(src[0].File),
-                                           src[0].
-                                           NegateBase ? VSF_FLAG_XYZ :
-                                           VSF_FLAG_NONE) | (src[0].
-                                                             RelAddr << 4);
-
-                       o_inst->src[1] =
-                           MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 0)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 1)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 2)),
-                                           SWIZZLE_ZERO,
-                                           t_src_class(src[1].File),
-                                           src[1].
-                                           NegateBase ? VSF_FLAG_XYZ :
-                                           VSF_FLAG_NONE) | (src[1].
-                                                             RelAddr << 4);
-
-                       o_inst->src[2] = ZERO_SRC_1;
-                       goto next;
-
-               case OPCODE_SUB:        //ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
-#if 1
-                       hw_op = (src[0].File == PROGRAM_TEMPORARY &&
-                                src[1].File ==
-                                PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
-                           R300_VPI_OUT_OP_MAD;
-
-                       o_inst->op =
-                           MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-                       o_inst->src[0] = t_src(vp, &src[0]);
-                       o_inst->src[1] = ONE_SRC_0;
-                       o_inst->src[2] =
-                           MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 0)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 1)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 2)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 3)),
-                                           t_src_class(src[1].File),
-                                           (!src[1].
-                                            NegateBase) ? VSF_FLAG_ALL :
-                                           VSF_FLAG_NONE) | (src[1].
-                                                             RelAddr << 4);
-#else
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_ADD,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-
-                       o_inst->src[0] = t_src(vp, &src[0]);
-                       o_inst->src[1] =
-                           MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 0)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 1)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 2)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[1].Swizzle, 3)),
-                                           t_src_class(src[1].File),
-                                           (!src[1].
-                                            NegateBase) ? VSF_FLAG_ALL :
-                                           VSF_FLAG_NONE) | (src[1].
-                                                             RelAddr << 4);
-                       o_inst->src[2] = 0;
-#endif
-                       goto next;
-
-               case OPCODE_ABS:        //MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_MAX,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-
-                       o_inst->src[0] = t_src(vp, &src[0]);
-                       o_inst->src[1] =
-                           MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 0)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 1)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 2)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 3)),
-                                           t_src_class(src[0].File),
-                                           (!src[0].
-                                            NegateBase) ? VSF_FLAG_ALL :
-                                           VSF_FLAG_NONE) | (src[0].
-                                                             RelAddr << 4);
-                       o_inst->src[2] = 0;
-                       goto next;
-
+                       inst = t_opcode_add(vp, vpi, inst, src);
+                       break;
+               case OPCODE_ARL:
+                       inst = t_opcode_arl(vp, vpi, inst, src);
+                       break;
+               case OPCODE_DP3:
+                       inst = t_opcode_dp3(vp, vpi, inst, src);
+                       break;
+               case OPCODE_DP4:
+                       inst = t_opcode_dp4(vp, vpi, inst, src);
+                       break;
+               case OPCODE_DPH:
+                       inst = t_opcode_dph(vp, vpi, inst, src);
+                       break;
+               case OPCODE_DST:
+                       inst = t_opcode_dst(vp, vpi, inst, src);
+                       break;
+               case OPCODE_EX2:
+                       inst = t_opcode_ex2(vp, vpi, inst, src);
+                       break;
+               case OPCODE_EXP:
+                       inst = t_opcode_exp(vp, vpi, inst, src);
+                       break;
                case OPCODE_FLR:
-                       /* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W}
-                          ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} TMP 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W */
-
-                       o_inst->op = MAKE_VSF_OP(R300_VPI_OUT_OP_FRC, u_temp_i,
-                                                t_dst_mask(vpi->DstReg.
-                                                           WriteMask),
-                                                VSF_OUT_CLASS_TMP);
-
-                       o_inst->src[0] = t_src(vp, &src[0]);
-                       o_inst->src[1] = ZERO_SRC_0;
-                       o_inst->src[2] = ZERO_SRC_0;
-                       o_inst++;
-
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_ADD,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-
-                       o_inst->src[0] = t_src(vp, &src[0]);
-                       o_inst->src[1] = MAKE_VSF_SOURCE(u_temp_i,
-                                                        VSF_IN_COMPONENT_X,
-                                                        VSF_IN_COMPONENT_Y,
-                                                        VSF_IN_COMPONENT_Z,
-                                                        VSF_IN_COMPONENT_W,
-                                                        VSF_IN_CLASS_TMP,
-                                                        /* Not 100% sure about this */
-                                                        (!src[0].
-                                                         NegateBase) ?
-                                                        VSF_FLAG_ALL :
-                                                        VSF_FLAG_NONE
-                                                        /*VSF_FLAG_ALL */ );
-
-                       o_inst->src[2] = ZERO_SRC_0;
-                       u_temp_i--;
-                       goto next;
-
-               case OPCODE_LG2:        // LG2 RESULT 1.X Y Z W PARAM 0{} {X X X X}
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_LG2,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-
-                       o_inst->src[0] =
-                           MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 0)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 0)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 0)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 0)),
-                                           t_src_class(src[0].File),
-                                           src[0].
-                                           NegateBase ? VSF_FLAG_ALL :
-                                           VSF_FLAG_NONE) | (src[0].
-                                                             RelAddr << 4);
-                       o_inst->src[1] = ZERO_SRC_0;
-                       o_inst->src[2] = ZERO_SRC_0;
-                       goto next;
-
-               case OPCODE_LIT:        //LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W}
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_LIT,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-                       /* NOTE: Users swizzling might not work. */
-                       o_inst->src[0] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 0)),       // x
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
-                                                        VSF_IN_COMPONENT_ZERO, // z
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y
-                                                        t_src_class(src[0].
-                                                                    File),
-                                                        src[0].
-                                                        NegateBase ?
-                                                        VSF_FLAG_ALL :
-                                                        VSF_FLAG_NONE) |
-                           (src[0].RelAddr << 4);
-                       o_inst->src[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)),       // y
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
-                                                        VSF_IN_COMPONENT_ZERO, // z
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
-                                                        t_src_class(src[0].
-                                                                    File),
-                                                        src[0].
-                                                        NegateBase ?
-                                                        VSF_FLAG_ALL :
-                                                        VSF_FLAG_NONE) |
-                           (src[0].RelAddr << 4);
-                       o_inst->src[2] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)),       // y
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
-                                                        VSF_IN_COMPONENT_ZERO, // z
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
-                                                        t_src_class(src[0].
-                                                                    File),
-                                                        src[0].
-                                                        NegateBase ?
-                                                        VSF_FLAG_ALL :
-                                                        VSF_FLAG_NONE) |
-                           (src[0].RelAddr << 4);
-                       goto next;
-
-               case OPCODE_DPH:        //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W}
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_DOT,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-
-                       o_inst->src[0] =
-                           MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 0)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 1)),
-                                           t_swizzle(GET_SWZ
-                                                     (src[0].Swizzle, 2)),
-                                           VSF_IN_COMPONENT_ONE,
-                                           t_src_class(src[0].File),
-                                           src[0].
-                                           NegateBase ? VSF_FLAG_XYZ :
-                                           VSF_FLAG_NONE) | (src[0].
-                                                             RelAddr << 4);
-                       o_inst->src[1] = t_src(vp, &src[1]);
-                       o_inst->src[2] = ZERO_SRC_1;
-                       goto next;
-
-               case OPCODE_XPD:
-                       /* mul r0, r1.yzxw, r2.zxyw
-                          mad r0, -r2.yzxw, r1.zxyw, r0
-                          NOTE: might need MAD_2
-                        */
-
-                       o_inst->op = MAKE_VSF_OP(R300_VPI_OUT_OP_MAD, u_temp_i,
-                                                t_dst_mask(vpi->DstReg.
-                                                           WriteMask),
-                                                VSF_OUT_CLASS_TMP);
-
-                       o_inst->src[0] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)),       // y
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
-                                                        t_src_class(src[0].
-                                                                    File),
-                                                        src[0].
-                                                        NegateBase ?
-                                                        VSF_FLAG_ALL :
-                                                        VSF_FLAG_NONE) |
-                           (src[0].RelAddr << 4);
-
-                       o_inst->src[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 2)),       // z
-                                                        t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x
-                                                        t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y
-                                                        t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w
-                                                        t_src_class(src[1].
-                                                                    File),
-                                                        src[1].
-                                                        NegateBase ?
-                                                        VSF_FLAG_ALL :
-                                                        VSF_FLAG_NONE) |
-                           (src[1].RelAddr << 4);
-
-                       o_inst->src[2] = ZERO_SRC_1;
-                       o_inst++;
-                       u_temp_i--;
-
-                       o_inst->op =
-                           MAKE_VSF_OP(R300_VPI_OUT_OP_MAD,
-                                       t_dst_index(vp, &vpi->DstReg),
-                                       t_dst_mask(vpi->DstReg.WriteMask),
-                                       t_dst_class(vpi->DstReg.File));
-
-                       o_inst->src[0] = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 1)),       // y
-                                                        t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z
-                                                        t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x
-                                                        t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w
-                                                        t_src_class(src[1].
-                                                                    File),
-                                                        (!src[1].
-                                                         NegateBase) ?
-                                                        VSF_FLAG_ALL :
-                                                        VSF_FLAG_NONE) |
-                           (src[1].RelAddr << 4);
-
-                       o_inst->src[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 2)),       // z
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y
-                                                        t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
-                                                        t_src_class(src[0].
-                                                                    File),
-                                                        src[0].
-                                                        NegateBase ?
-                                                        VSF_FLAG_ALL :
-                                                        VSF_FLAG_NONE) |
-                           (src[0].RelAddr << 4);
-
-                       o_inst->src[2] = MAKE_VSF_SOURCE(u_temp_i + 1,
-                                                        VSF_IN_COMPONENT_X,
-                                                        VSF_IN_COMPONENT_Y,
-                                                        VSF_IN_COMPONENT_Z,
-                                                        VSF_IN_COMPONENT_W,
-                                                        VSF_IN_CLASS_TMP,
-                                                        VSF_FLAG_NONE);
-
-                       goto next;
-
-               case OPCODE_RCC:
-                       fprintf(stderr, "Dont know how to handle op %d yet\n",
-                               vpi->Opcode);
-                       _mesa_exit(-1);
+                       inst =
+                           t_opcode_flr(vp, vpi, inst, src, /* FIXME */
+                                        &u_temp_i);
+                       break;
+               case OPCODE_FRC:
+                       inst = t_opcode_frc(vp, vpi, inst, src);
+                       break;
+               case OPCODE_LG2:
+                       inst = t_opcode_lg2(vp, vpi, inst, src);
+                       break;
+               case OPCODE_LIT:
+                       inst = t_opcode_lit(vp, vpi, inst, src);
+                       break;
+               case OPCODE_LOG:
+                       inst = t_opcode_log(vp, vpi, inst, src);
+                       break;
+               case OPCODE_MAD:
+                       inst = t_opcode_mad(vp, vpi, inst, src);
+                       break;
+               case OPCODE_MAX:
+                       inst = t_opcode_max(vp, vpi, inst, src);
+                       break;
+               case OPCODE_MIN:
+                       inst = t_opcode_min(vp, vpi, inst, src);
+                       break;
+               case OPCODE_MOV:
+                       inst = t_opcode_mov(vp, vpi, inst, src);
                        break;
-               case OPCODE_END:
+               case OPCODE_MUL:
+                       inst = t_opcode_mul(vp, vpi, inst, src);
+                       break;
+               case OPCODE_POW:
+                       inst = t_opcode_pow(vp, vpi, inst, src);
+                       break;
+               case OPCODE_RCP:
+                       inst = t_opcode_rcp(vp, vpi, inst, src);
+                       break;
+               case OPCODE_RSQ:
+                       inst = t_opcode_rsq(vp, vpi, inst, src);
+                       break;
+               case OPCODE_SGE:
+                       inst = t_opcode_sge(vp, vpi, inst, src);
+                       break;
+               case OPCODE_SLT:
+                       inst = t_opcode_slt(vp, vpi, inst, src);
+                       break;
+               case OPCODE_SUB:
+                       inst = t_opcode_sub(vp, vpi, inst, src);
+                       break;
+               case OPCODE_SWZ:
+                       inst = t_opcode_swz(vp, vpi, inst, src);
+                       break;
+               case OPCODE_XPD:
+                       inst =
+                           t_opcode_xpd(vp, vpi, inst, src, /* FIXME */
+                                        &u_temp_i);
                        break;
                default:
+                       assert(0);
                        break;
                }
-
-               o_inst->op =
-                   MAKE_VSF_OP(t_opcode(vpi->Opcode),
-                               t_dst_index(vp, &vpi->DstReg),
-                               t_dst_mask(vpi->DstReg.WriteMask),
-                               t_dst_class(vpi->DstReg.File));
-
-               if (are_srcs_scalar) {
-                       switch (operands) {
-                       case 1:
-                               o_inst->src[0] = t_src_scalar(vp, &src[0]);
-                               o_inst->src[1] = ZERO_SRC_0;
-                               o_inst->src[2] = ZERO_SRC_0;
-                               break;
-
-                       case 2:
-                               o_inst->src[0] = t_src_scalar(vp, &src[0]);
-                               o_inst->src[1] = t_src_scalar(vp, &src[1]);
-                               o_inst->src[2] = ZERO_SRC_1;
-                               break;
-
-                       case 3:
-                               o_inst->src[0] = t_src_scalar(vp, &src[0]);
-                               o_inst->src[1] = t_src_scalar(vp, &src[1]);
-                               o_inst->src[2] = t_src_scalar(vp, &src[2]);
-                               break;
-
-                       default:
-                               fprintf(stderr,
-                                       "scalars and op RCC not handled yet");
-                               _mesa_exit(-1);
-                               break;
-                       }
-               } else {
-                       switch (operands) {
-                       case 1:
-                               o_inst->src[0] = t_src(vp, &src[0]);
-                               o_inst->src[1] = ZERO_SRC_0;
-                               o_inst->src[2] = ZERO_SRC_0;
-                               break;
-
-                       case 2:
-                               o_inst->src[0] = t_src(vp, &src[0]);
-                               o_inst->src[1] = t_src(vp, &src[1]);
-                               o_inst->src[2] = ZERO_SRC_1;
-                               break;
-
-                       case 3:
-                               o_inst->src[0] = t_src(vp, &src[0]);
-                               o_inst->src[1] = t_src(vp, &src[1]);
-                               o_inst->src[2] = t_src(vp, &src[2]);
-                               break;
-
-                       default:
-                               fprintf(stderr,
-                                       "scalars and op RCC not handled yet");
-                               _mesa_exit(-1);
-                               break;
-                       }
-               }
-             next:;
        }
 
-       /* Will most likely segfault before we get here... fix later. */
-       if (o_inst - vp->program.body.i >= VSF_MAX_FRAGMENT_LENGTH / 4) {
+       vp->program.length = (inst - vp->program.body.i);
+       if (vp->program.length >= VSF_MAX_FRAGMENT_LENGTH) {
                vp->program.length = 0;
                vp->native = GL_FALSE;
-               return;
        }
-       vp->program.length = (o_inst - vp->program.body.i) * 4;
 #if 0
        fprintf(stderr, "hw program:\n");
        for (i = 0; i < vp->program.length; i++)
@@ -1065,7 +1309,8 @@ static void position_invariant(struct gl_program *prog)
        struct gl_program_parameter_list *paramList;
        int i;
 
-       gl_state_index tokens[STATE_LENGTH] = { STATE_MVP_MATRIX, 0, 0, 0, 0 };
+       gl_state_index tokens[STATE_LENGTH] =
+           { STATE_MVP_MATRIX, 0, 0, 0, 0 };
 
        /* tokens[4] = matrix modifier */
 #ifdef PREFER_DP4
@@ -1159,8 +1404,8 @@ static void insert_wpos(struct r300_vertex_program *vp,
                                prog->NumInstructions - 1);
        /* END */
        _mesa_copy_instructions(&vpi[prog->NumInstructions + 1],
-                               &prog->Instructions[prog->NumInstructions - 1],
-                               1);
+                               &prog->Instructions[prog->NumInstructions -
+                                                   1], 1);
        vpi_insert = &vpi[prog->NumInstructions - 1];
 
        vpi_insert[i].Opcode = OPCODE_MOV;
@@ -1206,8 +1451,8 @@ static void pos_as_texcoord(struct r300_vertex_program *vp,
        prog->NumTemporaries++;
 
        for (vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++) {
-               if (vpi->DstReg.File == PROGRAM_OUTPUT &&
-                   vpi->DstReg.Index == VERT_RESULT_HPOS) {
+               if (vpi->DstReg.File == PROGRAM_OUTPUT
+                   && vpi->DstReg.Index == VERT_RESULT_HPOS) {
                        vpi->DstReg.File = PROGRAM_TEMPORARY;
                        vpi->DstReg.Index = tempregi;
                }
@@ -1223,20 +1468,18 @@ static struct r300_vertex_program *build_program(struct r300_vertex_program_key
 
        vp = _mesa_calloc(sizeof(*vp));
        _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
-
        vp->wpos_idx = wpos_idx;
 
        if (mesa_vp->IsPositionInvariant) {
                position_invariant(&mesa_vp->Base);
        }
 
-       if (wpos_idx > -1)
+       if (wpos_idx > -1) {
                pos_as_texcoord(vp, &mesa_vp->Base);
+       }
 
        assert(mesa_vp->Base.NumInstructions);
-
        vp->num_temporaries = mesa_vp->Base.NumTemporaries;
-
        r300TranslateVertexShader(vp, mesa_vp->Base.Instructions);
 
        return vp;
@@ -1252,11 +1495,10 @@ void r300SelectVertexShader(r300ContextPtr r300)
        struct r300_vertex_program *vp;
        GLint wpos_idx;
 
-       vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
+       vpc =
+           (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
        InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
 
-       wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
-
        wpos_idx = -1;
        if (InputsRead & FRAG_BIT_WPOS) {
                for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
@@ -1271,28 +1513,35 @@ void r300SelectVertexShader(r300ContextPtr r300)
                InputsRead |= (FRAG_BIT_TEX0 << i);
                wpos_idx = i;
        }
+       wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
+       wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
+
+       wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
 
-       if (InputsRead & FRAG_BIT_COL0)
+       if (InputsRead & FRAG_BIT_COL0) {
                wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0;
+       }
 
-       if ((InputsRead & FRAG_BIT_COL1)        /*||
-                                                  (InputsRead & FRAG_BIT_FOGC) */ )
+       if ((InputsRead & FRAG_BIT_COL1)) {
                wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL1;
+       }
 
-       for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
-               if (InputsRead & (FRAG_BIT_TEX0 << i))
+       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+               if (InputsRead & (FRAG_BIT_TEX0 << i)) {
                        wanted_key.OutputsWritten |=
                            1 << (VERT_RESULT_TEX0 + i);
+               }
+       }
 
-       wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
        if (vpc->mesa_program.IsPositionInvariant) {
                /* we wan't position don't we ? */
                wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS);
+               wanted_key.OutputsWritten |= (1 << VERT_RESULT_HPOS);
        }
 
        for (vp = vpc->progs; vp; vp = vp->next)
-               if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) ==
-                   0) {
+               if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key))
+                   == 0) {
                        r300->selected_vp = vp;
                        return;
                }
index 252d5a901f41b7c630282faf468ded5b2bb8e14f..3df0eee799108b83af29504abea50bc85593ade9 100644 (file)
@@ -3,11 +3,6 @@
 
 #include "r300_reg.h"
 
-typedef struct {
-       GLuint op;
-       GLuint src[3];
-} VERTEX_SHADER_INSTRUCTION;
-
 #define VSF_FLAG_X     1
 #define VSF_FLAG_Y     2
 #define VSF_FLAG_Z     4
index 3dd821a4d396621a107c9eb6cf8a3a6ab8c98de6..4ce2f60b4f329d460eb03b7fd25193752639465c 100644 (file)
@@ -131,7 +131,9 @@ static __inline__ void savage_draw_point (savageContextPtr imesa,
    u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);
    const GLfloat x = tmp->v.x;
    const GLfloat y = tmp->v.y;
-   const GLfloat sz = imesa->glCtx->Point._Size * .5;
+   const GLfloat sz = 0.5 * CLAMP(imesa->glCtx->Point.Size,
+                                  imesa->glCtx->Const.MinPointSize,
+                                  imesa->glCtx->Const.MaxPointSize);
    GLuint j;
 
    *(float *)&vb[0] = x - sz;
@@ -164,7 +166,9 @@ static __inline__ void savage_draw_line (savageContextPtr imesa,
                                         savageVertexPtr v1 ) {
    GLuint vertsize = imesa->HwVertexSize;
    u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);
-   GLfloat width = imesa->glCtx->Line._Width;
+   const GLfloat width = CLAMP(imesa->glCtx->Line.Width,
+                               imesa->glCtx->Const.MinLineWidth,
+                               imesa->glCtx->Const.MaxLineWidth);
    GLfloat dx, dy, ix, iy;
    GLuint j;
 
@@ -234,7 +238,9 @@ static __inline__ void savage_ptex_line (savageContextPtr imesa,
                                         savageVertexPtr v1 ) {
    GLuint vertsize = imesa->HwVertexSize;
    u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);
-   GLfloat width = imesa->glCtx->Line._Width;
+   const GLfloat width = CLAMP(imesa->glCtx->Line.Width,
+                               imesa->glCtx->Const.MinLineWidth,
+                               imesa->glCtx->Const.MaxLineWidth);
    GLfloat dx, dy, ix, iy;
    savageVertex tmp0, tmp1;
    GLuint j;
@@ -281,7 +287,9 @@ static __inline__ void savage_ptex_point (savageContextPtr imesa,
    u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize);
    const GLfloat x = v0->v.x;
    const GLfloat y = v0->v.y;
-   const GLfloat sz = imesa->glCtx->Point._Size * .5;
+   const GLfloat sz = 0.5 * CLAMP(imesa->glCtx->Point.Size,
+                                  imesa->glCtx->Const.MinPointSize,
+                                  imesa->glCtx->Const.MaxPointSize);
    savageVertex tmp;
    GLuint j;
 
index 96f9ae27fc1a63e9c81b272f92d2303b716127d9..7252a7e7dc6402304880c83627be974c74e389b7 100644 (file)
@@ -184,7 +184,7 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst)
       }
    }
 
-   dst->pointSize = ctx->Point._Size;
+   dst->pointSize = ctx->Point.Size;
 }
 
 
index 6c6511b7e53ab189311ce87ea2db6df6a7d36c6a..e95a424698c4d41928d162d158864a93adb6a8a4 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.1
+ * Version:  7.1
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -63,6 +63,9 @@
 #include "drivers/common/driverfuncs.h"
 
 
+/**
+ * Pixel formats we support:
+ */
 #define PF_B8G8R8     1
 #define PF_B8G8R8A8   2
 #define PF_B5G6R5     3
@@ -70,7 +73,7 @@
 #define PF_CI8        5
 
 
-/*
+/**
  * Derived from Mesa's GLvisual class.
  */
 struct GLFBDevVisualRec {
@@ -80,7 +83,7 @@ struct GLFBDevVisualRec {
    int pixelFormat;
 };
 
-/*
+/**
  * Derived from Mesa's GLframebuffer class.
  */
 struct GLFBDevBufferRec {
@@ -92,7 +95,7 @@ struct GLFBDevBufferRec {
    GLuint bytesPerPixel;
 };
 
-/*
+/**
  * Derived from Mesa's GLcontext class.
  */
 struct GLFBDevContextRec {
@@ -103,7 +106,7 @@ struct GLFBDevContextRec {
    GLFBDevBufferPtr curBuffer;
 };
 
-/*
+/**
  * Derived from Mesa's gl_renderbuffer class.
  */
 struct GLFBDevRenderbufferRec {
@@ -114,11 +117,6 @@ struct GLFBDevRenderbufferRec {
 };
 
 
-
-#define GLFBDEV_CONTEXT(CTX)  ((GLFBDevContextPtr) (CTX))
-#define GLFBDEV_BUFFER(BUF)  ((GLFBDevBufferPtr) (BUF))
-
-
 /**********************************************************************/
 /* Internal device driver functions                                   */
 /**********************************************************************/
@@ -151,7 +149,7 @@ update_state( GLcontext *ctx, GLuint new_state )
 static void
 get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
 {
-   const GLFBDevBufferPtr fbdevbuffer = GLFBDEV_BUFFER(buffer);
+   const GLFBDevBufferPtr fbdevbuffer = (GLFBDevBufferPtr) buffer;
    *width = fbdevbuffer->var.xres;
    *height = fbdevbuffer->var.yres;
 }
@@ -389,8 +387,8 @@ glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
          /* ignored for now */
          break;
       case GLFBDEV_MULTISAMPLE:
-        numSamples = attrib[1];
-        attrib++;
+         numSamples = attrib[1];
+         attrib++;
          break;
       default:
          /* unexpected token */
@@ -406,36 +404,36 @@ glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
       alphaBits = varInfo->transp.length;
 
       if (fixInfo->visual == FB_VISUAL_TRUECOLOR ||
-         fixInfo->visual == FB_VISUAL_DIRECTCOLOR) {
-        if(varInfo->bits_per_pixel == 24
-           && varInfo->red.offset == 16
-           && varInfo->green.offset == 8
-           && varInfo->blue.offset == 0)
-           vis->pixelFormat = PF_B8G8R8;
-
-        else if(varInfo->bits_per_pixel == 32
-                && varInfo->red.offset == 16
-                && varInfo->green.offset == 8
-                && varInfo->blue.offset == 0)
-           vis->pixelFormat = PF_B8G8R8A8;
-
-        else if(varInfo->bits_per_pixel == 16
-                && varInfo->red.offset == 11
-                && varInfo->green.offset == 5
-                && varInfo->blue.offset == 0)
-           vis->pixelFormat = PF_B5G6R5;
-
-        else if(varInfo->bits_per_pixel == 16
-                && varInfo->red.offset == 10
-                && varInfo->green.offset == 5
-                && varInfo->blue.offset == 0)
-           vis->pixelFormat = PF_B5G5R5;
-
-        else {
-           _mesa_problem(NULL, "Unsupported fbdev RGB visual/bitdepth!\n");
-           _mesa_free(vis);
-           return NULL;
-        }
+          fixInfo->visual == FB_VISUAL_DIRECTCOLOR) {
+         if (varInfo->bits_per_pixel == 24
+             && varInfo->red.offset == 16
+             && varInfo->green.offset == 8
+             && varInfo->blue.offset == 0) {
+            vis->pixelFormat = PF_B8G8R8;
+         }
+         else if (varInfo->bits_per_pixel == 32
+                  && varInfo->red.offset == 16
+                  && varInfo->green.offset == 8
+                  && varInfo->blue.offset == 0) {
+            vis->pixelFormat = PF_B8G8R8A8;
+         }
+         else if (varInfo->bits_per_pixel == 16
+                  && varInfo->red.offset == 11
+                  && varInfo->green.offset == 5
+                  && varInfo->blue.offset == 0) {
+            vis->pixelFormat = PF_B5G6R5;
+         }
+         else if (varInfo->bits_per_pixel == 16
+                  && varInfo->red.offset == 10
+                  && varInfo->green.offset == 5
+                  && varInfo->blue.offset == 0) {
+            vis->pixelFormat = PF_B5G5R5;
+         }
+         else {
+            _mesa_problem(NULL, "Unsupported fbdev RGB visual/bitdepth!\n");
+            _mesa_free(vis);
+            return NULL;
+         }
       }
    }
    else {
@@ -578,7 +576,7 @@ new_glfbdev_renderbuffer(void *bufferStart, const GLFBDevVisualPtr visual)
 
       rb->rowStride = visual->var.xres_virtual * visual->var.bits_per_pixel / 8;
       rb->bottom = (GLubyte *) bufferStart
-         + (visual->var.yres - 1) * rb->rowStride;
+                 + (visual->var.yres - 1) * rb->rowStride;
 
       rb->Base.Width = visual->var.xres;
       rb->Base.Height = visual->var.yres;
@@ -635,7 +633,7 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
                           &frontrb->Base);
    /* add back renderbuffer */
    if (visual->glvisual.doubleBufferMode) {
-      int malloced = !backBuffer;
+      const int malloced = !backBuffer;
       if (malloced) {
          /* malloc a back buffer */
          backBuffer = _mesa_malloc(size);
@@ -647,8 +645,11 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
       }
 
       backrb = new_glfbdev_renderbuffer(backBuffer, visual);
-      if(malloced)
-        backrb->mallocedBuffer = GL_TRUE;
+      if (!backrb) {
+         /* out of mem */
+         return NULL;
+      }
+      backrb->mallocedBuffer = malloced;
 
       _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_BACK_LEFT,
                              &backrb->Base);
@@ -682,16 +683,10 @@ glFBDevDestroyBuffer( GLFBDevBufferPtr buffer )
       if (buffer == curDraw || buffer == curRead) {
          glFBDevMakeCurrent( NULL, NULL, NULL);
       }
-#if 0
-      /* free the software depth, stencil, accum buffers */
-      _mesa_free_framebuffer_data(&buffer->glframebuffer);
-      _mesa_free(buffer);
-#else
       {
          struct gl_framebuffer *fb = &buffer->glframebuffer;
          _mesa_unreference_framebuffer(&fb);
       }
-#endif
    }
 }
 
index fb23d210db7bc60de11f86349f355c143b219323..dad3dc116043c5bbc752e3bb1bdfd41233069a29 100644 (file)
 /* We're essentially building part of GDI here, so define this so that
  * we get the right export linkage. */
 #ifdef __MINGW32__
-#include <GL/gl.h>
+
+#include <stdarg.h>
+#include <windef.h>
+#include <wincon.h>
+#include <winbase.h>
+
+#  if defined(BUILD_GL32)
+#    define WINGDIAPI __declspec(dllexport)    
+#  else
+#    define __W32API_USE_DLLIMPORT__
+#  endif
+
+#include <wingdi.h>
+#include "GL/mesa_wgl.h"
 #include <stdlib.h>
+
 #else
+
 #define _GDI32_
-#endif
 #include <windows.h>
 
-#include "glapi.h"
+#endif
 
+#include "glapi.h"
 #include "GL/wmesa.h"   /* protos for wmesa* functions */
 
 /*
@@ -339,7 +354,7 @@ WINGDIAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc)
 }
 
 WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
-                                           const PIXELFORMATDESCRIPTOR *ppfd)
+                                       const PIXELFORMATDESCRIPTOR *ppfd)
 {
     (void) hdc;
     
@@ -392,12 +407,12 @@ static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar,
     
     bitDevice = CreateCompatibleDC(fontDevice);
     
-    // Swap fore and back colors so the bitmap has the right polarity
+    /* Swap fore and back colors so the bitmap has the right polarity */
     tempColor = GetBkColor(bitDevice);
     SetBkColor(bitDevice, GetTextColor(bitDevice));
     SetTextColor(bitDevice, tempColor);
     
-    // Place chars based on base line
+    /* Place chars based on base line */
     VERIFY(SetTextAlign(bitDevice, TA_BASELINE) != GDI_ERROR ? 1 : 0);
     
     for(i = 0; i < (int)numChars; i++) {
@@ -410,36 +425,36 @@ static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar,
        
        curChar = (char)(i + firstChar);
        
-       // Find how high/wide this character is
+       /* Find how high/wide this character is */
        VERIFY(GetTextExtentPoint32(bitDevice, &curChar, 1, &size));
        
-       // Create the output bitmap
+       /* Create the output bitmap */
        charWidth = size.cx;
        charHeight = size.cy;
-       // Round up to the next multiple of 32 bits
+       /* Round up to the next multiple of 32 bits */
        bmapWidth = ((charWidth + 31) / 32) * 32;   
        bmapHeight = charHeight;
        bitObject = CreateCompatibleBitmap(bitDevice,
                                           bmapWidth,
                                           bmapHeight);
-       //VERIFY(bitObject);
+       /* VERIFY(bitObject); */
        
-       // Assign the output bitmap to the device
+       /* Assign the output bitmap to the device */
        origBmap = SelectObject(bitDevice, bitObject);
        (void) VERIFY(origBmap);
        
        VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
        
-       // Use our source font on the device
+       /* Use our source font on the device */
        VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
        
-       // Draw the character
+       /* Draw the character */
        VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1));
        
-       // Unselect our bmap object
+       /* Unselect our bmap object */
        VERIFY(SelectObject(bitDevice, origBmap));
        
-       // Convert the display dependant representation to a 1 bit deep DIB
+       /* Convert the display dependant representation to a 1 bit deep DIB */
        numBytes = (bmapWidth * bmapHeight) / 8;
        bmap = malloc(numBytes);
        dibInfo->bmiHeader.biWidth = bmapWidth;
@@ -447,24 +462,24 @@ static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar,
        res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
                        dibInfo,
                        DIB_RGB_COLORS);
-       //VERIFY(res);
+       /* VERIFY(res); */
        
-       // Create the GL object
+       /* Create the GL object */
        glNewList(i + listBase, GL_COMPILE);
        glBitmap(bmapWidth, bmapHeight, 0.0, (GLfloat)metric.tmDescent,
                 (GLfloat)charWidth, 0.0,
                 bmap);
        glEndList();
-       // CheckGL();
+       /* CheckGL(); */
        
-       // Destroy the bmap object
+       /* Destroy the bmap object */
        DeleteObject(bitObject);
        
-       // Deallocate the bitmap data
+       /* Deallocate the bitmap data */
        free(bmap);
     }
     
-    // Destroy the DC
+    /* Destroy the DC */
     VERIFY(DeleteDC(bitDevice));
     
     free(dibInfo);
index 2eec188912e28a425c77bf5212d97f4458aa192e..5b67439f0f2577f106e63491b698ff7b804132e0 100644 (file)
@@ -6,6 +6,7 @@
 #include "wmesadef.h"
 #include "colors.h"
 #include <GL/wmesa.h>
+#include <winuser.h>
 #include "context.h"
 #include "extensions.h"
 #include "framebuffer.h"
@@ -114,7 +115,7 @@ static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC)
 {
     pwfb->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
 
-    // Only 16 and 32 bit targets are supported now
+    /* Only 16 and 32 bit targets are supported now */
     assert(pwfb->cColorBits == 0 ||
           pwfb->cColorBits == 16 || 
           pwfb->cColorBits == 32);
@@ -1171,7 +1172,7 @@ WMesaContext WMesaCreateContext(HDC hDC,
     /* I do not understand this contributed code */
     /* Support memory and device contexts */
     if(WindowFromDC(hDC) != NULL) {
-       c->hDC = GetDC(WindowFromDC(hDC)); // huh ????
+       c->hDC = GetDC(WindowFromDC(hDC)); /* huh ???? */
     }
     else {
        c->hDC = hDC;
@@ -1404,6 +1405,7 @@ void WMesaSwapBuffers( HDC hdc )
  * table entries.  Hopefully, I'll find a better solution.  The
  * dispatch table generation scripts ought to be making these dummy
  * stubs as well. */
+#if !defined(__MINGW32__) || !defined(GL_NO_STDCALL)
 void gl_dispatch_stub_543(void){}
 void gl_dispatch_stub_544(void){}
 void gl_dispatch_stub_545(void){}
@@ -1471,3 +1473,4 @@ void gl_dispatch_stub_769(void){}
 void gl_dispatch_stub_770(void){}
 void gl_dispatch_stub_771(void){}
 
+#endif
index 97b063a8babbf2bc3d80e5c375e0c30eac49afd6..83a42e608241d2ddf0913278d08e0ab2039d11a4 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef WMESADEF_H
 #define WMESADEF_H
-
+#ifdef __MINGW32__
+#include <windows.h>
+#endif
 #include "context.h"
 
 
diff --git a/src/mesa/drivers/x11/Makefile b/src/mesa/drivers/x11/Makefile
new file mode 100644 (file)
index 0000000..0ab1dc6
--- /dev/null
@@ -0,0 +1,2 @@
+default:
+       cd ../.. ; make
\ No newline at end of file
index 1587df66bcd48f1ce8e8db76427d1cc30826326b..7a170b4d3d10b7e0eb3fddd5b9e03bc4397e10ff 100644 (file)
@@ -296,6 +296,11 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo,
       }
    }
 
+   if (stereoFlag) {
+      /* stereo not supported */
+      return NULL;
+   }
+
    /* Comparing IDs uses less memory but sometimes fails. */
    /* XXX revisit this after 3.0 is finished. */
    if (_mesa_getenv("MESA_GLX_VISUAL_HACK"))
@@ -1079,7 +1084,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
             else {
                stereo_flag = GL_TRUE;
             }
-            return NULL; /* stereo not supported */
+            break;
         case GLX_AUX_BUFFERS:
            parselist++;
             numAux = *parselist++;
index eaa277db4ad1c7e1f289d42d368fc50ae86c251c..f20e8104fb3930c0b9e4d70dfb68f6df0a91707a 100644 (file)
@@ -81,6 +81,9 @@
 #include "tnl/t_pipeline.h"
 #include "drivers/common/driverfuncs.h"
 
+#include "state_tracker/st_public.h"
+#include "pipe/softpipe/sp_context.h"
+
 /**
  * Global X driver lock
  */
@@ -1566,6 +1569,10 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
    xmesa_register_swrast_functions( mesaCtx );
    _swsetup_Wakeup(mesaCtx);
 
+
+   st_create_context( mesaCtx,
+                     softpipe_create() );
+   
    return c;
 }
 
index 51d183bb4354ba536307a606b0c2149cf26b8592..8fbd9a783b0489c4f24cf022800bbfbbc0abbaf3 100644 (file)
@@ -35,6 +35,7 @@
 #include "imports.h"
 #include "framebuffer.h"
 #include "renderbuffer.h"
+#include "pipe/p_state.h"
 
 
 #if defined(USE_XSHM) && !defined(XFree86Server)
@@ -268,6 +269,8 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
    rb->Height = height;
    rb->InternalFormat = internalFormat;
 
+   rb->surface->resize(rb->surface, width, height);
+
    return GL_TRUE;
 }
 
@@ -317,6 +320,8 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
       xrb->origin4 = NULL;
    }
 
+   rb->surface->resize(rb->surface, width, height);
+
    return GL_TRUE;
 }
 
@@ -352,6 +357,9 @@ xmesa_new_renderbuffer(GLcontext *ctx, GLuint name, const GLvisual *visual,
          xrb->Base.IndexBits = visual->indexBits;
       }
       /* only need to set Red/Green/EtcBits fields for user-created RBs */
+
+      xrb->Base.surface = xmesa_new_surface(xrb);
+
    }
    return xrb;
 }
index c8546236fbf3644b222a96e16149e7ddab152265..57254148561a6950ae880d3a395825315139f83a 100644 (file)
 #include "tnl/tnl.h"
 #include "tnl/t_context.h"
 
+#include "pipe/softpipe/sp_context.h"
+#include "state_tracker/st_public.h"
+#include "state_tracker/st_context.h"
+#include "state_tracker/st_draw.h"
 
 
 /*
@@ -391,6 +395,7 @@ clear_buffers(GLcontext *ctx, GLbitfield buffers)
 
       /* we can't handle color or index masking */
       if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
+#if 0
          if (buffers & BUFFER_BIT_FRONT_LEFT) {
             /* clear front color buffer */
             struct gl_renderbuffer *frontRb
@@ -414,6 +419,15 @@ clear_buffers(GLcontext *ctx, GLbitfield buffers)
                buffers &= ~BUFFER_BIT_BACK_LEFT;
             }
          }
+#else
+         /* Clear with state-tracker/pipe interface */
+         struct st_context *st = st_context(ctx);
+         GLboolean color = (buffers & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) ? 1: 0;
+         GLboolean depth = (buffers & BUFFER_BIT_DEPTH) ? 1 : 0;
+         GLboolean stencil = (buffers & BUFFER_BIT_STENCIL) ? 1 : 0;
+         GLboolean accum = (buffers & BUFFER_BIT_ACCUM) ? 1 : 0;
+         st_clear(st, color, depth, stencil, accum);
+#endif
       }
    }
    if (buffers)
@@ -828,6 +842,9 @@ xmesa_update_state( GLcontext *ctx, GLbitfield new_state )
    _vbo_InvalidateState( ctx, new_state );
    _swsetup_InvalidateState( ctx, new_state );
 
+   st_invalidate_state( ctx, new_state );
+
+
    if (ctx->DrawBuffer->Name != 0)
       return;
 
index a24966b3aeb41ec5f4d645f349855b2ccfaad751..3776891e2eca5c7d44ac50d80c18f1e1fffd0280 100644 (file)
@@ -1303,6 +1303,17 @@ static void put_row_rgb_TRUEDITHER_ximage( RGB_SPAN_ARGS )
 }
 
 
+
+static void *get_pointer_4_ximage( GLcontext *ctx, 
+                                  struct gl_renderbuffer *rb, 
+                                  GLint x, GLint y )
+{
+   GET_XRB(xrb);
+   return PIXEL_ADDR4(xrb, x, y);
+}
+
+
+
 /*
  * Write a span of PF_8A8B8G8R-format pixels to an ximage.
  */
@@ -4593,6 +4604,7 @@ xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb,
          xrb->Base.PutMonoRow    = put_mono_row_8A8B8G8R_ximage;
          xrb->Base.PutValues     = put_values_8A8B8G8R_ximage;
          xrb->Base.PutMonoValues = put_mono_values_8A8B8G8R_ximage;
+        xrb->Base.GetPointer    = get_pointer_4_ximage;
       }
       break;
    case PF_8A8R8G8B:
@@ -4609,6 +4621,7 @@ xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb,
          xrb->Base.PutMonoRow    = put_mono_row_8A8R8G8B_ximage;
          xrb->Base.PutValues     = put_values_8A8R8G8B_ximage;
          xrb->Base.PutMonoValues = put_mono_values_8A8R8G8B_ximage;
+        xrb->Base.GetPointer    = get_pointer_4_ximage;
       }
       break;
    case PF_8R8G8B:
diff --git a/src/mesa/drivers/x11/xm_surface.c b/src/mesa/drivers/x11/xm_surface.c
new file mode 100644 (file)
index 0000000..17f5f28
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file xm_surface.c
+ * Code to allow the softpipe code to write to X windows/buffers.
+ * This is a bit of a hack for now.  We've basically got two different
+ * abstractions for color buffers: gl_renderbuffer and softpipe_surface.
+ * They'll need to get merged someday...
+ * For now, they're separate things that point to each other.
+ */
+
+
+#include "glxheader.h"
+#include "GL/xmesa.h"
+#include "xmesaP.h"
+#include "context.h"
+#include "imports.h"
+#include "macros.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "pipe/softpipe/sp_context.h"
+#include "pipe/softpipe/sp_surface.h"
+
+
+static void *
+map_surface_buffer(struct pipe_buffer *pb, GLuint access_mode)
+{
+   /* no-op */
+   return NULL;
+}
+
+
+static void
+unmap_surface_buffer(struct pipe_buffer *pb)
+{
+   /* no-op */
+}
+
+
+static INLINE struct xmesa_renderbuffer *
+xmesa_rb(struct softpipe_surface *sps)
+{
+   return (struct xmesa_renderbuffer *) sps->surface.rb;
+}
+
+
+/**
+ * quad reading/writing
+ * These functions are just wrappers around the existing renderbuffer
+ * functions.
+ */
+
+static void
+read_quad_f(struct softpipe_surface *sps, GLint x, GLint y,
+            GLfloat (*rgba)[NUM_CHANNELS])
+{
+   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
+   GLubyte temp[16];
+   GLfloat *dst = (GLfloat *) rgba;
+   GLuint i;
+   GET_CURRENT_CONTEXT(ctx);
+   xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y,     temp);
+   xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y + 1, temp + 8);
+   for (i = 0; i < 16; i++) {
+      dst[i] = UBYTE_TO_FLOAT(temp[i]);
+   }
+}
+
+static void
+read_quad_f_swz(struct softpipe_surface *sps, GLint x, GLint y,
+                GLfloat (*rrrr)[QUAD_SIZE])
+{
+   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
+   GLubyte temp[16];
+   GLfloat *dst = (GLfloat *) rrrr;
+   GLuint i, j;
+   GET_CURRENT_CONTEXT(ctx);
+   xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y,     temp);
+   xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y + 1, temp + 8);
+   for (i = 0; i < 4; i++) {
+      for (j = 0; j < 4; j++) {
+         dst[j * 4 + i] = UBYTE_TO_FLOAT(temp[i * 4 + j]);
+      }
+   }
+}
+
+static void
+write_quad_f(struct softpipe_surface *sps, GLint x, GLint y,
+             GLfloat (*rgba)[NUM_CHANNELS])
+{
+   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
+   GLubyte temp[16];
+   const GLfloat *src = (const GLfloat *) rgba;
+   GLuint i;
+   GET_CURRENT_CONTEXT(ctx);
+   for (i = 0; i < 16; i++) {
+      UNCLAMPED_FLOAT_TO_UBYTE(temp[i], src[i]);
+   }
+   xrb->Base.PutRow(ctx, &xrb->Base, 2, x, y,     temp,     NULL);
+   xrb->Base.PutRow(ctx, &xrb->Base, 2, x, y + 1, temp + 8, NULL);
+}
+
+static void
+write_quad_f_swz(struct softpipe_surface *sps, GLint x, GLint y,
+                 GLfloat (*rrrr)[QUAD_SIZE])
+{
+   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
+   GLubyte temp[16];
+   const GLfloat *src = (const GLfloat *) rrrr;
+   GLuint i, j;
+   GET_CURRENT_CONTEXT(ctx);
+   for (i = 0; i < 4; i++) {
+      for (j = 0; j < 4; j++) {
+         UNCLAMPED_FLOAT_TO_UBYTE(temp[j * 4 + i], src[i * 4 + j]);
+      }
+   }
+   xrb->Base.PutRow(ctx, &xrb->Base, 2, x, y,     temp,     NULL);
+   xrb->Base.PutRow(ctx, &xrb->Base, 2, x, y + 1, temp + 8, NULL);
+}
+
+static void
+read_quad_ub(struct softpipe_surface *sps, GLint x, GLint y,
+             GLubyte (*rgba)[NUM_CHANNELS])
+{
+   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
+   GET_CURRENT_CONTEXT(ctx);
+   xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y,     rgba);
+   xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y + 1, rgba + 2);
+}
+
+static void
+write_quad_ub(struct softpipe_surface *sps, GLint x, GLint y,
+              GLubyte (*rgba)[NUM_CHANNELS])
+{
+   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
+   GET_CURRENT_CONTEXT(ctx);
+   xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y,     rgba);
+   xrb->Base.GetRow(ctx, &xrb->Base, 2, x, y + 1, rgba + 2);
+}
+
+static void
+write_mono_row_ub(struct softpipe_surface *sps, GLuint count, GLint x, GLint y,
+                  GLubyte rgba[NUM_CHANNELS])
+{
+   struct xmesa_renderbuffer *xrb = xmesa_rb(sps);
+   GET_CURRENT_CONTEXT(ctx);
+   xrb->Base.PutMonoRow(ctx, &xrb->Base, count, x, y, rgba, NULL);
+}
+
+
+static void
+resize_surface(struct pipe_surface *ps, GLuint width, GLuint height)
+{
+   ps->width = width;
+   ps->height = height;
+}
+
+
+/**
+ * Called to create a pipe_surface for each X renderbuffer.
+ */
+struct pipe_surface *
+xmesa_new_surface(struct xmesa_renderbuffer *xrb)
+{
+   struct softpipe_surface *sps;
+
+   sps = CALLOC_STRUCT(softpipe_surface);
+   if (!sps)
+      return NULL;
+
+   sps->surface.rb = xrb;
+   sps->surface.width = xrb->Base.Width;
+   sps->surface.height = xrb->Base.Height;
+
+   sps->read_quad_f = read_quad_f;
+   sps->read_quad_f_swz = read_quad_f_swz;
+   sps->read_quad_ub = read_quad_ub;
+   sps->write_quad_f = write_quad_f;
+   sps->write_quad_f_swz = write_quad_f_swz;
+   sps->write_quad_ub = write_quad_ub;
+   sps->write_mono_row_ub = write_mono_row_ub;
+
+   sps->surface.buffer.map = map_surface_buffer;
+   sps->surface.buffer.unmap = unmap_surface_buffer;
+   sps->surface.resize = resize_surface;
+
+   return &sps->surface;
+}
index 95c6d7c1d20a80faa234d4d2f64485c953771001..9f17083f90124d972072053cbea9dc5dfa371e4b 100644 (file)
@@ -1443,6 +1443,46 @@ do {                                   \
 #endif
 
 
+#if 0
+GLboolean xmesa_get_cbuf_details( GLcontext *ctx,
+                                 void **ptr,
+                                 GLuint *cpp,
+                                 GLint *stride,
+                                 GLuint *format )
+{
+   XMesaContext xmesa = XMESA_CONTEXT(ctx);
+   struct gl_framebuffer *fb = ctx->DrawBuffer;
+   struct gl_renderbuffer *crb = fb->_ColorDrawBuffers[0][0];
+   struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(crb->Wrapped);
+
+   *ptr = crb->GetPointer(ctx, crb, 0, 0);
+   *stride = ((GLubyte *)crb->GetPointer(ctx, crb, 0, 1) - 
+             (GLubyte *)crb->GetPointer(ctx, crb, 0, 0));
+
+   if (!ptr) 
+      goto bad;
+
+   switch (xmesa->pixelformat) {
+   case PF_8A8B8G8R:
+   case PF_8A8R8G8B:
+      *format = 1;             /* whatever */
+      *cpp = 4;
+      break;
+   default:
+      goto bad;
+   }
+
+   return GL_TRUE;
+
+ bad:
+   *ptr = NULL;
+   *stride = 0;
+   *format = 0;
+   return GL_FALSE;   
+}
+#endif
+
+
 /**
  * Return pointer to line drawing function, or NULL if we should use a
  * swrast fallback.
index e3d7cf381f7c52d2d43faa955ca8ac30df10099e..daf6a3f9424577903b32b9933191ca05e7b18476 100644 (file)
@@ -196,6 +196,8 @@ struct xmesa_renderbuffer
    GLint bottom;       /* used for FLIP macro, equals height - 1 */
 
    ClearFunc clearFunc;
+
+   void *pSurface;      /** pipe surface */
 };
 
 
@@ -583,4 +585,11 @@ extern void xmesa_register_swrast_functions( GLcontext *ctx );
 #define ENABLE_EXT_timer_query 0 /* may not have 64-bit GLuint64EXT */
 #endif
 
+
+struct pipe_surface;
+
+struct pipe_surface *
+xmesa_new_surface(struct xmesa_renderbuffer *xrb);
+
+
 #endif
index 1899975213f6be6f7f0a799ae46740ab767fe9ab..72091b0789c4727aa485d84dda1524534dfd059a 100644 (file)
@@ -31,8 +31,8 @@
 #include "context.h"
 #include "imports.h"
 #include "macros.h"
-#include "glapioffsets.h"
-#include "dispatch.h"
+#include "glapi/glapioffsets.h"
+#include "glapi/dispatch.h"
 
 typedef void (GLAPIENTRY *array_func)( const void * );
 
index efe5a77d5811af1c4d3d6e7bb1cc3133d47e347f..924d7134a2701fbd38fb695c6c055c308f4fd48b 100644 (file)
 
 
 #include "glheader.h"
-#include "glapi.h"
-#include "glapitable.h"
 #include "macros.h"
 #include "colormac.h"
 #include "api_loopback.h"
-#include "glthread.h"
 #include "mtypes.h"
-#include "dispatch.h"
+#include "glapi/glapi.h"
+#include "glapi/glapitable.h"
+#include "glapi/glthread.h"
+#include "glapi/dispatch.h"
 
 /* KW: A set of functions to convert unusual Color/Normal/Vertex/etc
  * calls to a smaller set of driver-provided formats.  Currently just
index 0c1a35361f16ab9d36d5e546621122b377e6377f..3df64362eab691ad658da83d0bba62e7ca42825e 100644 (file)
@@ -31,7 +31,7 @@
 #include "light.h"
 #include "macros.h"
 #include "dlist.h"
-#include "dispatch.h"
+#include "glapi/dispatch.h"
 
 
 /**
index 3d20ba7d1443c83ad7ff3e4791cf4365870ca0ef..841c6a530263e40984aa8b31421192a2bf5bb237 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.1
+ * Version:  7.0.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -100,6 +100,11 @@ _mesa_validate_DrawElements(GLcontext *ctx,
                          (const GLubyte *) indices);
       }
    }
+   else {
+      /* not using a VBO */
+      if (!indices)
+         return GL_FALSE;
+   }
 
    if (ctx->Const.CheckArrayBounds) {
       /* find max array index */
@@ -170,6 +175,16 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
        && !(ctx->VertexProgram._Enabled && ctx->Array.ArrayObj->VertexAttrib[0].Enabled))
       return GL_FALSE;
 
+   /* Vertex buffer object tests */
+   if (ctx->Array.ElementArrayBufferObj->Name) {
+      /* XXX re-use code from above? */
+   }
+   else {
+      /* not using VBO */
+      if (!indices)
+         return GL_FALSE;
+   }
+
    if (ctx->Const.CheckArrayBounds) {
       /* Find max array index.
        * We don't trust the user's start and end values.
index d601ee461e69c6c9d5b2d381ac4e9ca1457e55bc..f08f99d8e17fb5e62dca9851f1c835d94c435749 100644 (file)
@@ -46,7 +46,7 @@
 #include "bufferobj.h"
 #endif
 #include "arrayobj.h"
-#include "dispatch.h"
+#include "glapi/dispatch.h"
 
 
 /**
index 92d8ceda2922682afdf942a28774e3d997f0fde9..00e4c8328e559edc2047de55d091f5a9ca1332f0 100644 (file)
 #include "fog.h"
 #include "framebuffer.h"
 #include "get.h"
-#include "glthread.h"
-#include "glapioffsets.h"
 #include "histogram.h"
 #include "hint.h"
 #include "hash.h"
-#include "atifragshader.h"
 #include "light.h"
 #include "lines.h"
 #include "macros.h"
 #include "pixel.h"
 #include "points.h"
 #include "polygon.h"
-#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
-#include "program.h"
-#endif
 #include "queryobj.h"
 #include "rastpos.h"
 #include "simple_list.h"
 #include "varray.h"
 #include "version.h"
 #include "vtxfmt.h"
+#include "glapi/glthread.h"
+#include "glapi/glapioffsets.h"
+#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
+#include "shader/program.h"
+#endif
+#include "shader/shader_api.h"
+#include "shader/atifragshader.h"
 #if _HAVE_FULL_GL
 #include "math/m_translate.h"
 #include "math/m_matrix.h"
 #include "math/m_xform.h"
 #include "math/mathmod.h"
 #endif
-#include "shader_api.h"
 
 #ifdef USE_SPARC_ASM
 #include "sparc/sparc.h"
index b6a9d1314932648c874665915f72d4688ff882e0..099912aa15259d707cc5c2977b0d15ba092b17ac 100644 (file)
@@ -49,7 +49,7 @@
 #define CONTEXT_H
 
 
-#include "glapi.h"
+#include "glapi/glapi.h"
 #include "imports.h"
 #include "mtypes.h"
 
index 91ddcbf9ed6c47f79df0a0ea3907dfe0178cb541..293ee5fa349dd9a148a5c445ee57faf1ca5f85d2 100644 (file)
 #include "api_arrayelt.h"
 #include "api_loopback.h"
 #include "config.h"
-#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
-#include "arbprogram.h"
-#include "program.h"
-#endif
 #include "attrib.h"
 #include "blend.h"
 #include "buffers.h"
@@ -57,7 +53,7 @@
 #include "extensions.h"
 #include "feedback.h"
 #include "get.h"
-#include "glapi.h"
+#include "glapi/glapi.h"
 #include "hash.h"
 #include "histogram.h"
 #include "image.h"
 #include "texstate.h"
 #include "mtypes.h"
 #include "varray.h"
+#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
+#include "shader/arbprogram.h"
+#include "shader/program.h"
+#endif
 #if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
-#include "nvprogram.h"
-#include "program.h"
+#include "shader/nvprogram.h"
+#include "shader/program.h"
 #endif
 #if FEATURE_ATI_fragment_shader
-#include "atifragshader.h"
+#include "shader/atifragshader.h"
 #endif
 
 #include "math/m_matrix.h"
 #include "math/m_xform.h"
 
-#include "dispatch.h"
+#include "glapi/dispatch.h"
 
 
 /**
index df3095232de470d2447b6726765e25f1244ed536..40f66d7da2d5d64b94ece7cd14908694630239e4 100644 (file)
@@ -32,7 +32,7 @@
 
 
 #include "imports.h"
-#include "glthread.h"
+#include "glapi/glthread.h"
 
 
 
index f737c74f357a7ce8aa3e5b9b8336545bd5d71d54..c9b30d3252829993b796366dcf096f7928f441c3 100644 (file)
@@ -65,7 +65,9 @@ compute_depth_max(struct gl_framebuffer *fb)
       fb->_DepthMax = 0xffffffff;
    }
    fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
-   fb->_MRD = 1.0;  /* Minimum resolvable depth value, for polygon offset */
+
+   /* Minimum resolvable depth value, for polygon offset */
+   fb->_MRD = 1.0 / fb->_DepthMaxF;
 }
 
 
index 63dd002a41264bbc095b07a73415e7bba08fec9b..fd4127558a839e4d53bd550e971decc0a994798e 100644 (file)
@@ -92,7 +92,7 @@
 #endif
 
 #ifdef WGLAPI
-#undef WGLAPI
+#      undef WGLAPI
 #endif
 
 #if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__)) && !defined(BUILD_FOR_SNAP)
index 2d5bcc3e01e9c0f28fb555d881978d05d13376d5..ffb2c4d946e47024471f8a84ca15d1651e77989c 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "glheader.h"
 #include "imports.h"
-#include "glthread.h"
+#include "glapi/glthread.h"
 #include "hash.h"
 
 
index e2e7f806ab165349386c6ecf2a2512932be8d1a3..ba46cdc1b1709d2bc0b13ee54a1cc48a61073cc4 100644 (file)
@@ -3648,11 +3648,13 @@ _mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n,
     * Try simple cases first
     */
    if (transferOps == 0 &&
+       !ctx->Pixel.MapStencilFlag &&
        srcType == GL_UNSIGNED_BYTE &&
        dstType == GL_UNSIGNED_BYTE) {
       _mesa_memcpy(dest, source, n * sizeof(GLubyte));
    }
    else if (transferOps == 0 &&
+            !ctx->Pixel.MapStencilFlag &&
             srcType == GL_UNSIGNED_INT &&
             dstType == GL_UNSIGNED_INT &&
             !srcPacking->SwapBytes) {
@@ -3668,19 +3670,17 @@ _mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n,
       extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source,
                            srcPacking);
 
-      if (transferOps) {
-         if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
-            /* shift and offset indexes */
-            shift_and_offset_ci(ctx, n, indexes);
-         }
+      if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+         /* shift and offset indexes */
+         shift_and_offset_ci(ctx, n, indexes);
+      }
 
-         if (ctx->Pixel.MapStencilFlag) {
-            /* Apply stencil lookup table */
-            GLuint mask = ctx->PixelMaps.StoS.Size - 1;
-            GLuint i;
-            for (i=0;i<n;i++) {
-               indexes[i] = ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
-            }
+      if (ctx->Pixel.MapStencilFlag) {
+         /* Apply stencil lookup table */
+         const GLuint mask = ctx->PixelMaps.StoS.Size - 1;
+         GLuint i;
+         for (i = 0; i < n; i++) {
+            indexes[i] = ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
          }
       }
 
@@ -3882,9 +3882,19 @@ _mesa_pack_stencil_span( const GLcontext *ctx, GLuint n,
         }                                                               \
     } while (0)
 
+
+/**
+ * Unpack a row of depth/z values from memory, returning GLushort, GLuint
+ * or GLfloat values.
+ * The glPixelTransfer (scale/bias) params will be applied.
+ *
+ * \param dstType  one of GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, GL_FLOAT
+ * \param depthMax  max value for returned GLushort or GLuint values
+ *                  (ignored for GLfloat).
+ */
 void
 _mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
-                         GLenum dstType, GLvoid *dest, GLfloat depthScale,
+                         GLenum dstType, GLvoid *dest, GLuint depthMax,
                          GLenum srcType, const GLvoid *source,
                          const struct gl_pixelstore_attrib *srcPacking )
 {
@@ -3907,7 +3917,9 @@ _mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
          }
          return;
       }
-      if (srcType == GL_UNSIGNED_SHORT && dstType == GL_UNSIGNED_INT) {
+      if (srcType == GL_UNSIGNED_SHORT
+          && dstType == GL_UNSIGNED_INT
+          && depthMax == 0xffffffff) {
          const GLushort *src = (const GLushort *) source;
          GLuint *dst = (GLuint *) dest;
          GLuint i;
@@ -3955,7 +3967,7 @@ _mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
          break;
       case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */
          if (dstType == GL_UNSIGNED_INT &&
-             depthScale == (GLfloat) 0xffffff &&
+             depthMax == 0xffffff &&
              ctx->Pixel.DepthScale == 1.0 &&
              ctx->Pixel.DepthBias == 0.0) {
             const GLuint *src = (const GLuint *) source;
@@ -4033,16 +4045,16 @@ _mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
    if (dstType == GL_UNSIGNED_INT) {
       GLuint *zValues = (GLuint *) dest;
       GLuint i;
-      if (depthScale <= (GLfloat) 0xffffff) {
+      if (depthMax <= 0xffffff) {
          /* no overflow worries */
          for (i = 0; i < n; i++) {
-            zValues[i] = (GLuint) (depthValues[i] * depthScale);
+            zValues[i] = (GLuint) (depthValues[i] * (GLfloat) depthMax);
          }
       }
       else {
          /* need to use double precision to prevent overflow problems */
          for (i = 0; i < n; i++) {
-            GLdouble z = depthValues[i] * depthScale;
+            GLdouble z = depthValues[i] * (GLfloat) depthMax;
             if (z >= (GLdouble) 0xffffffff)
                zValues[i] = 0xffffffff;
             else
@@ -4053,14 +4065,14 @@ _mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
    else if (dstType == GL_UNSIGNED_SHORT) {
       GLushort *zValues = (GLushort *) dest;
       GLuint i;
-      ASSERT(depthScale <= 65535.0);
+      ASSERT(depthMax <= 0xffff);
       for (i = 0; i < n; i++) {
-         zValues[i] = (GLushort) (depthValues[i] * depthScale);
+         zValues[i] = (GLushort) (depthValues[i] * (GLfloat) depthMax);
       }
    }
    else {
       ASSERT(dstType == GL_FLOAT);
-      ASSERT(depthScale == 1.0F);
+      /*ASSERT(depthMax == 1.0F);*/
    }
 }
 
index 990398a7c45fb6d7b442bc98b0df432c1cc467e1..2a16989fa7edc422aa512e6d4e037196b3413632 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.2
+ * Version:  7.1
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -181,7 +181,7 @@ _mesa_pack_stencil_span( const GLcontext *ctx, GLuint n,
 
 extern void
 _mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
-                         GLenum dstType, GLvoid *dest, GLfloat depthScale,
+                         GLenum dstType, GLvoid *dest, GLuint depthMax,
                          GLenum srcType, const GLvoid *source,
                          const struct gl_pixelstore_attrib *srcPacking );
 
index 8a5dfdb4b80e3ccffd9ad89f49e69aec0a61690f..3ae56c8b0b64ba66c70ec00833945f398228b43f 100644 (file)
@@ -575,7 +575,11 @@ _mesa_ffs(int i)
  *          if no bits set.
  */
 int
+#ifdef __MINGW32__
+_mesa_ffsll(long val)
+#else
 _mesa_ffsll(long long val)
+#endif
 {
 #ifdef ffsll
    return ffsll(val);
index 9be8014a131388aa70f81c8b79f15d8d9dca6b65..ebdfc452a7aa838ef845126c6094584dda7260d5 100644 (file)
@@ -700,7 +700,11 @@ extern int
 _mesa_ffs(int i);
 
 extern int
+#ifdef __MINGW32__
+_mesa_ffsll(long i);
+#else
 _mesa_ffsll(long long i);
+#endif
 
 extern unsigned int
 _mesa_bitcount(unsigned int n);
index dc7195d4ebf7389600c0b54c1cab5bdd8bb892b0..0c2dbf915a1901503bb9a7f8867e902601e0c7ed 100644 (file)
@@ -55,9 +55,6 @@ _mesa_LineWidth( GLfloat width )
 
    FLUSH_VERTICES(ctx, _NEW_LINE);
    ctx->Line.Width = width;
-   ctx->Line._Width = CLAMP(width,
-                           ctx->Const.MinLineWidth,
-                           ctx->Const.MaxLineWidth);
 
    if (ctx->Driver.LineWidth)
       ctx->Driver.LineWidth(ctx, width);
@@ -105,13 +102,12 @@ _mesa_LineStipple( GLint factor, GLushort pattern )
  * Initializes __GLcontextRec::Line and line related constants in
  * __GLcontextRec::Const.
  */
-void GLAPIENTRY _mesa_init_line( GLcontext * ctx )
+void GLAPIENTRY
+_mesa_init_line( GLcontext * ctx )
 {
-   /* Line group */
    ctx->Line.SmoothFlag = GL_FALSE;
    ctx->Line.StippleFlag = GL_FALSE;
    ctx->Line.Width = 1.0;
-   ctx->Line._Width = 1.0;
    ctx->Line.StipplePattern = 0xffff;
    ctx->Line.StippleFactor = 1;
 }
index 05c08c19fec8398a8dcfa009d88f2651886e2d1c..d70df5d945c5cc3812bb5a428ec6c247d4410bf4 100644 (file)
@@ -38,8 +38,8 @@
 #include "glheader.h"
 #include <GL/internal/glcore.h>        /* __GLcontextModes (GLvisual) */
 #include "config.h"            /* Hardwired parameters */
-#include "glapitable.h"
-#include "glthread.h"
+#include "glapi/glapitable.h"
+#include "glapi/glthread.h"
 #include "math/m_matrix.h"     /* GLmatrix */
 #include "bitset.h"
 
@@ -126,6 +126,8 @@ struct gl_pixelstore_attrib;
 struct gl_texture_format;
 struct gl_texture_image;
 struct gl_texture_object;
+struct st_context;
+struct pipe_surface;
 typedef struct __GLcontextRec GLcontext;
 typedef struct __GLcontextModesRec GLvisual;
 typedef struct gl_framebuffer GLframebuffer;
@@ -917,7 +919,6 @@ struct gl_line_attrib
    GLushort StipplePattern;    /**< Stipple pattern */
    GLint StippleFactor;                /**< Stipple repeat factor */
    GLfloat Width;              /**< Line width */
-   GLfloat _Width;             /**< Clamped Line width */
 };
 
 
@@ -1063,7 +1064,6 @@ struct gl_point_attrib
 {
    GLboolean SmoothFlag;       /**< True if GL_POINT_SMOOTH is enabled */
    GLfloat Size;               /**< User-specified point size */
-   GLfloat _Size;              /**< Size clamped to Const.Min/MaxPointSize */
    GLfloat Params[3];          /**< GL_EXT_point_parameters */
    GLfloat MinSize, MaxSize;   /**< GL_EXT_point_parameters */
    GLfloat Threshold;          /**< GL_EXT_point_parameters */
@@ -1133,13 +1133,13 @@ struct gl_stencil_attrib
  * An index for each type of texture object
  */
 /*@{*/
-#define TEXTURE_1D_INDEX    0
-#define TEXTURE_2D_INDEX    1
-#define TEXTURE_3D_INDEX    2
-#define TEXTURE_CUBE_INDEX  3
-#define TEXTURE_RECT_INDEX  4
-#define TEXTURE_1D_ARRAY_INDEX    5
-#define TEXTURE_2D_ARRAY_INDEX    6
+#define TEXTURE_1D_INDEX       0
+#define TEXTURE_2D_INDEX       1
+#define TEXTURE_3D_INDEX       2
+#define TEXTURE_CUBE_INDEX     3
+#define TEXTURE_RECT_INDEX     4
+#define TEXTURE_1D_ARRAY_INDEX 5
+#define TEXTURE_2D_ARRAY_INDEX 6
 /*@}*/
 
 /**
@@ -1147,13 +1147,13 @@ struct gl_stencil_attrib
  * Used for Texture.Unit[]._ReallyEnabled flags.
  */
 /*@{*/
-#define TEXTURE_1D_BIT   (1 << TEXTURE_1D_INDEX)
-#define TEXTURE_2D_BIT   (1 << TEXTURE_2D_INDEX)
-#define TEXTURE_3D_BIT   (1 << TEXTURE_3D_INDEX)
-#define TEXTURE_CUBE_BIT (1 << TEXTURE_CUBE_INDEX)
-#define TEXTURE_RECT_BIT (1 << TEXTURE_RECT_INDEX)
-#define TEXTURE_1D_ARRAY_BIT   (1 << TEXTURE_1D_ARRAY_INDEX)
-#define TEXTURE_2D_ARRAY_BIT   (1 << TEXTURE_2D_ARRAY_INDEX)
+#define TEXTURE_1D_BIT       (1 << TEXTURE_1D_INDEX)
+#define TEXTURE_2D_BIT       (1 << TEXTURE_2D_INDEX)
+#define TEXTURE_3D_BIT       (1 << TEXTURE_3D_INDEX)
+#define TEXTURE_CUBE_BIT     (1 << TEXTURE_CUBE_INDEX)
+#define TEXTURE_RECT_BIT     (1 << TEXTURE_RECT_INDEX)
+#define TEXTURE_1D_ARRAY_BIT (1 << TEXTURE_1D_ARRAY_INDEX)
+#define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX)
 /*@}*/
 
 
@@ -1327,8 +1327,6 @@ struct gl_texture_format
 };
 
 
-#define MAX_3D_TEXTURE_SIZE (1 << (MAX_3D_TEXTURE_LEVELS - 1))
-
 /**
  * Texture image state.  Describes the dimensions of a texture image,
  * the texel format and pointers to Texel Fetch functions.
@@ -1393,7 +1391,7 @@ struct gl_texture_image
 #define FACE_NEG_Y   3
 #define FACE_POS_Z   4
 #define FACE_NEG_Z   5
-#define MAX_FACES  6
+#define MAX_FACES    6
 /*@}*/
 
 
@@ -2193,12 +2191,11 @@ struct gl_shared_state
     * \todo Improve the granularity of locking.
     */
    /*@{*/
-   _glthread_Mutex TexMutex;              /**< texobj thread safety */
-   GLuint TextureStateStamp;              /**< state notification for shared tex  */
+   _glthread_Mutex TexMutex;           /**< texobj thread safety */
+   GLuint TextureStateStamp;           /**< state notification for shared tex */
    /*@}*/
 
 
-
    /**
     * \name Vertex/fragment programs
     */
@@ -2272,6 +2269,8 @@ struct gl_renderbuffer
    GLubyte StencilBits;
    GLvoid *Data;        /**< This may not be used by some kinds of RBs */
 
+   struct pipe_surface *surface;
+
    /* Used to wrap one renderbuffer around another: */
    struct gl_renderbuffer *Wrapped;
 
@@ -3107,7 +3106,7 @@ struct __GLcontextRec
    void *swsetup_context;
    void *swtnl_context;
    void *swtnl_im;
-   void *acache_context;
+   struct st_context *st;
    void *aelt_context;
    /*@}*/
 };
index 0f562420b085fa689dfd36ddb68d3da417fa4bf7..e83db5de78d60e64b720637e1aa2eb333207a0ff 100644 (file)
@@ -57,10 +57,6 @@ _mesa_PointSize( GLfloat size )
 
    FLUSH_VERTICES(ctx, _NEW_POINT);
    ctx->Point.Size = size;
-   /* XXX correct clamp limits? */
-   ctx->Point._Size = CLAMP(ctx->Point.Size,
-                           ctx->Point.MinSize,
-                           ctx->Point.MaxSize);
 
    if (ctx->Driver.PointSize)
       ctx->Driver.PointSize(ctx, size);
@@ -253,7 +249,6 @@ _mesa_init_point(GLcontext *ctx)
 
    ctx->Point.SmoothFlag = GL_FALSE;
    ctx->Point.Size = 1.0;
-   ctx->Point._Size = 1.0;
    ctx->Point.Params[0] = 1.0;
    ctx->Point.Params[1] = 0.0;
    ctx->Point.Params[2] = 0.0;
index 0e59ba615a783bd597f1ffe49d78efa616d5b9c4..fc04dde3f49a2ccf1544f697365be3ea303634f0 100644 (file)
 #include "queryobj.h"
 #include "mtypes.h"
 
+#if 1 /*PIPE*/
+#include "pipe/p_context.h"
+#include "state_tracker/st_context.h"
+#endif
+
 
 /**
  * Allocate a new query object.  This is a fallback routine called via
@@ -220,6 +225,10 @@ _mesa_BeginQueryARB(GLenum target, GLuint id)
    q->Result = 0;
    q->Ready = GL_FALSE;
 
+#if 1 /*PIPE*/
+   ctx->st->pipe->reset_occlusion_counter(ctx->st->pipe);
+#endif
+
    if (target == GL_SAMPLES_PASSED_ARB) {
       ctx->Query.CurrentOcclusionObject = q;
    }
@@ -282,6 +291,12 @@ _mesa_EndQueryARB(GLenum target)
       /* if we're using software rendering/querying */
       q->Ready = GL_TRUE;
    }
+
+#if 1 /*PIPE*/
+   if (target == GL_SAMPLES_PASSED_ARB) {
+      q->Result = ctx->st->pipe->get_occlusion_counter(ctx->st->pipe);
+   }
+#endif
 }
 
 
index 6f1d7c39605697225d67a94eebff21bf447a9777..a900de169e5aa2ba595cb45b362df1c7dfacf767 100644 (file)
 
 #include "rbadaptors.h"
 
+#include "pipe/softpipe/sp_z_surface.h"
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+
 
 /* 32-bit color index format.  Not a public format. */
 #define COLOR_INDEX32 0x424243
@@ -1091,6 +1095,8 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
       rb->PutValues = put_values_ushort;
       rb->PutMonoValues = put_mono_values_ushort;
       rb->DepthBits = 8 * sizeof(GLushort);
+      rb->surface
+         = (struct pipe_surface *) softpipe_new_z_surface(PIPE_FORMAT_U_Z16);
       pixelSize = sizeof(GLushort);
       break;
    case GL_DEPTH_COMPONENT24:
@@ -1113,6 +1119,8 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
          rb->_ActualFormat = GL_DEPTH_COMPONENT32;
          rb->DepthBits = 32;
       }
+      rb->surface
+         = (struct pipe_surface *) softpipe_new_z_surface(PIPE_FORMAT_U_Z32);
       pixelSize = sizeof(GLuint);
       break;
    case GL_DEPTH_STENCIL_EXT:
@@ -1130,6 +1138,8 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
       rb->PutMonoValues = put_mono_values_uint;
       rb->DepthBits = 24;
       rb->StencilBits = 8;
+      rb->surface
+         = (struct pipe_surface *) softpipe_new_z_surface(PIPE_FORMAT_Z24_S8);
       pixelSize = sizeof(GLuint);
       break;
    case GL_COLOR_INDEX8_EXT:
@@ -1193,13 +1203,27 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
 
    /* free old buffer storage */
    if (rb->Data) {
-      _mesa_free(rb->Data);
+      if (rb->surface) {
+         /* pipe surface */
+      }
+      else {
+         /* legacy renderbuffer */
+         _mesa_free(rb->Data);
+      }
       rb->Data = NULL;
    }
 
    if (width > 0 && height > 0) {
       /* allocate new buffer storage */
-      rb->Data = _mesa_malloc(width * height * pixelSize);
+      if (rb->surface) {
+         /* pipe surface */
+         rb->surface->resize(rb->surface, width, height);
+         rb->Data = rb->surface->buffer.ptr;
+      }
+      else {
+         /* legacy renderbuffer */
+         rb->Data = _mesa_malloc(width * height * pixelSize);
+      }
       if (rb->Data == NULL) {
          rb->Width = 0;
          rb->Height = 0;
index 58be1f46e570513a23febfce0bb531ce8f31cca2..7bf8808767002b6d40aca00d3a931c2c24b1376d 100644 (file)
@@ -83,7 +83,7 @@ _mesa_CreateShader(GLenum type)
 }
 
 
-GLhandleARB APIENTRY
+GLhandleARB GLAPIENTRY
 _mesa_CreateShaderObjectARB(GLenum type)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -99,7 +99,7 @@ _mesa_CreateProgram(void)
 }
 
 
-GLhandleARB APIENTRY
+GLhandleARB GLAPIENTRY
 _mesa_CreateProgramObjectARB(void)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -319,7 +319,7 @@ _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
 
 
 #if 0
-GLint APIENTRY
+GLint GLAPIENTRY
 _mesa_GetUniformLocation(GLuint program, const GLcharARB *name)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -336,7 +336,7 @@ _mesa_GetHandleARB(GLenum pname)
 }
 
 
-GLint APIENTRY
+GLint GLAPIENTRY
 _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
 {
    GET_CURRENT_CONTEXT(ctx);
index 0a83abc7ddac587cb6f8edacf2d9bbe920f863aa..444f227760182c102d6e9d40ab8e46457dbac701 100644 (file)
 #include "accum.h"
 #include "api_loopback.h"
 #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
-#include "arbprogram.h"
+#include "shader/arbprogram.h"
 #endif
 #if FEATURE_ATI_fragment_shader
-#include "atifragshader.h"
+#include "shader/atifragshader.h"
 #endif
 #include "attrib.h"
 #include "blend.h"
 #include "mtypes.h"
 #include "varray.h"
 #if FEATURE_NV_vertex_program
-#include "nvprogram.h"
+#include "shader/nvprogram.h"
 #endif
 #if FEATURE_NV_fragment_program
-#include "nvprogram.h"
-#include "program.h"
+#include "shader/nvprogram.h"
+#include "shader/program.h"
 #include "texenvprogram.h"
 #endif
 #if FEATURE_ARB_shader_objects
 #include "shaders.h"
 #endif
 #include "debug.h"
-#include "dispatch.h"
+#include "glapi/dispatch.h"
 
 
 
@@ -1068,7 +1068,7 @@ update_tricaps(GLcontext *ctx, GLbitfield new_state)
    if (1/*new_state & _NEW_POINT*/) {
       if (ctx->Point.SmoothFlag)
          ctx->_TriangleCaps |= DD_POINT_SMOOTH;
-      if (ctx->Point._Size != 1.0F)
+      if (ctx->Point.Size != 1.0F)
          ctx->_TriangleCaps |= DD_POINT_SIZE;
       if (ctx->Point._Attenuated)
          ctx->_TriangleCaps |= DD_POINT_ATTEN;
@@ -1082,7 +1082,7 @@ update_tricaps(GLcontext *ctx, GLbitfield new_state)
          ctx->_TriangleCaps |= DD_LINE_SMOOTH;
       if (ctx->Line.StippleFlag)
          ctx->_TriangleCaps |= DD_LINE_STIPPLE;
-      if (ctx->Line._Width != 1.0)
+      if (ctx->Line.Width != 1.0)
          ctx->_TriangleCaps |= DD_LINE_WIDTH;
    }
 
index 411d51cfcc60c066b92b02fdaf9d97b0ff81b96a..b6991f45ed85c416128b2640cd97c059f4767b8d 100644 (file)
@@ -302,7 +302,12 @@ const struct gl_texture_format _mesa_texformat_rgba_fxt1 = {
 
 #define FX64_NATIVE 1
 
+#ifdef __MINGW32__
+typedef unsigned long Fx64;
+#else
 typedef unsigned long long Fx64;
+#endif
+
 
 #define FX64_MOV32(a, b) a = b
 #define FX64_OR32(a, b)  a |= b
index 1a46c10ffa319f9ba84ece6ea89e0007701dea44..72b54b27d9a6a61d2c42adc1b74a1ce3031717a4 100644 (file)
 #include "glheader.h"
 #include "macros.h"
 #include "enums.h"
-#include "prog_parameter.h"
-#include "prog_instruction.h"
-#include "prog_print.h"
-#include "prog_statevars.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_print.h"
+#include "shader/prog_statevars.h"
 #include "texenvprogram.h"
 
 /**
index f902365b9bd9b37718832013a723b8a6e333114e..3420d8e2bafd675a6dfa5c4dd679ddf135dd97dc 100644 (file)
@@ -1264,6 +1264,10 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
  * A hardware driver might override this function if, for example, the
  * max 3D texture size is 512x512x64 (i.e. not a cube).
  *
+ * Note that width, height, depth == 0 is not an error.  However, a
+ * texture with zero width/height/depth will be considered "incomplete"
+ * and texturing will effectively be disabled.
+ *
  * \param target  one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
  *                GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
  *                GL_PROXY_TEXTURE_CUBE_MAP_ARB.
@@ -1293,7 +1297,7 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(width - 2 * border) != 1) ||
+           width >0 && _mesa_bitcount(width - 2 * border) != 1) ||
           level >= ctx->Const.MaxTextureLevels) {
          /* bad width or level */
          return GL_FALSE;
@@ -1303,10 +1307,10 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(width - 2 * border) != 1) ||
+           width > 0 && _mesa_bitcount(width - 2 * border) != 1) ||
           height < 2 * border || height > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(height - 2 * border) != 1) ||
+           height > 0 && _mesa_bitcount(height - 2 * border) != 1) ||
           level >= ctx->Const.MaxTextureLevels) {
          /* bad width or height or level */
          return GL_FALSE;
@@ -1316,21 +1320,21 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(width - 2 * border) != 1) ||
+           width > 0 && _mesa_bitcount(width - 2 * border) != 1) ||
           height < 2 * border || height > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(height - 2 * border) != 1) ||
+           height > 0 && _mesa_bitcount(height - 2 * border) != 1) ||
           depth < 2 * border || depth > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(depth - 2 * border) != 1) ||
+           depth > 0 && _mesa_bitcount(depth - 2 * border) != 1) ||
           level >= ctx->Const.Max3DTextureLevels) {
          /* bad width or height or depth or level */
          return GL_FALSE;
       }
       return GL_TRUE;
    case GL_PROXY_TEXTURE_RECTANGLE_NV:
-      if (width < 1 || width > ctx->Const.MaxTextureRectSize ||
-          height < 1 || height > ctx->Const.MaxTextureRectSize ||
+      if (width < 0 || width > ctx->Const.MaxTextureRectSize ||
+          height < 0 || height > ctx->Const.MaxTextureRectSize ||
           level != 0) {
          /* bad width or height or level */
          return GL_FALSE;
@@ -1340,10 +1344,10 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(width - 2 * border) != 1) ||
+           width > 0 && _mesa_bitcount(width - 2 * border) != 1) ||
           height < 2 * border || height > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(height - 2 * border) != 1) ||
+           height > 0 && _mesa_bitcount(height - 2 * border) != 1) ||
           level >= ctx->Const.MaxCubeTextureLevels) {
          /* bad width or height */
          return GL_FALSE;
@@ -1353,7 +1357,7 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(width - 2 * border) != 1) ||
+           width > 0 && _mesa_bitcount(width - 2 * border) != 1) ||
           level >= ctx->Const.MaxTextureLevels) {
          /* bad width or level */
          return GL_FALSE;
@@ -1367,10 +1371,10 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
       if (width < 2 * border || width > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(width - 2 * border) != 1) ||
+           width > 0 && _mesa_bitcount(width - 2 * border) != 1) ||
           height < 2 * border || height > 2 + maxSize ||
           (!ctx->Extensions.ARB_texture_non_power_of_two &&
-           _mesa_bitcount(height - 2 * border) != 1) ||
+           height > 0 && _mesa_bitcount(height - 2 * border) != 1) ||
           level >= ctx->Const.MaxTextureLevels) {
          /* bad width or height or level */
          return GL_FALSE;
@@ -1472,7 +1476,7 @@ texture_error_check( GLcontext *ctx, GLenum target,
       if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) {
          proxy_target = GL_PROXY_TEXTURE_1D;
          height = 1;
-         width = 1;
+         depth = 1;
       }
       else {
          _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
index 9b8a06df1452ff902f93c8b2ca76df28e39dfef2..3b5151ed17135f95e89a74e7b648dfdc52d4c99b 100644 (file)
@@ -1077,7 +1077,7 @@ _mesa_texstore_rgba(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_z32(TEXSTORE_PARAMS)
 {
-   const GLfloat depthScale = (GLfloat) 0xffffffff;
+   const GLuint depthScale = 0xffffffff;
    (void) dims;
    ASSERT(dstFormat == &_mesa_texformat_z32);
    ASSERT(dstFormat->TexelBytes == sizeof(GLuint));
@@ -1124,7 +1124,7 @@ _mesa_texstore_z32(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_z16(TEXSTORE_PARAMS)
 {
-   const GLfloat depthScale = 65535.0f;
+   const GLuint depthScale = 0xffff;
    (void) dims;
    ASSERT(dstFormat == &_mesa_texformat_z16);
    ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
@@ -2319,6 +2319,8 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
 {
+   const GLuint depthScale = 0xffffff;
+
    ASSERT(dstFormat == &_mesa_texformat_z24_s8);
    ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT);
    ASSERT(srcType == GL_UNSIGNED_INT_24_8_EXT);
@@ -2357,7 +2359,7 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
             _mesa_unpack_depth_span(ctx, srcWidth,
                                     GL_UNSIGNED_INT, /* dst type */
                                     dstRow, /* dst addr */
-                                    (GLfloat) 0xffffff, /* depthScale */
+                                    depthScale,
                                     srcType, src, srcPacking);
             /* get the 8-bit stencil values */
             _mesa_unpack_stencil_span(ctx, srcWidth,
index bf1ad0165e66e8fd1a5b89c1fa2b9f1d433edb96..fe4a7c684f6344bd84aa8cb94324de71e3953419 100644 (file)
@@ -32,7 +32,7 @@
 #include "mtypes.h"
 #include "varray.h"
 #include "arrayobj.h"
-#include "dispatch.h"
+#include "glapi/dispatch.h"
 
 
 /**
index 783b06558d516f642da5f8ee6722c8a4f8e40cdb..6f5d01e40f2d9ad8e5e4ebf2f1584645456e401c 100644 (file)
@@ -29,8 +29,8 @@
 #define PRE_LOOPBACK( FUNC )
 #endif
 
-#include "dispatch.h"
-#include "glapioffsets.h"
+#include "glapi/dispatch.h"
+#include "glapi/glapioffsets.h"
 
 static void GLAPIENTRY TAG(ArrayElement)( GLint i )
 {
index 42ffd4133d3ad0c07a6ebb80669384b90888691e..d324673c5d772714a79be38240e7ac3d47884648 100644 (file)
@@ -37,8 +37,8 @@
  */
 
 
-#include "glheader.h"
-#include "config.h"
+#include "main/glheader.h"
+#include "main/config.h"
 #include "m_eval.h"
 
 static GLfloat inv_tab[MAX_EVAL_ORDER];
index a23cbd402e69aff17c2d5b0e11d6799371b198f4..d73ecaafb28f2b4b47fd59b4e869ded6f6b9b9ef 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef _M_EVAL_H
 #define _M_EVAL_H
 
-#include "glheader.h"
+#include "main/glheader.h"
 
 void _math_init_eval( void );
 
index 0bcf96005c79213251899d12148b7c0376e9dedb..c677682d5060d616f8777b384d68190284fc2339 100644 (file)
@@ -26,8 +26,8 @@
 #ifndef _M_TRANSLATE_H_
 #define _M_TRANSLATE_H_
 
-#include "config.h"
-#include "mtypes.h"            /* hack for GLchan */
+#include "main/config.h"
+#include "main/mtypes.h"               /* hack for GLchan */
 
 
 /**
index fa3f57a8e5a8e7d458cf3f79e3c1f692b2bab9dd..901ae5b416ab4d392544609fb60e978ff2b3abc7 100644 (file)
@@ -33,8 +33,8 @@
  * 3. Transformation of a point p by a matrix M is: p' = M * p
  */
 
-#include "glheader.h"
-#include "macros.h"
+#include "main/glheader.h"
+#include "main/macros.h"
 
 #include "m_eval.h"
 #include "m_matrix.h"
diff --git a/src/mesa/pipe/Makefile b/src/mesa/pipe/Makefile
new file mode 100644 (file)
index 0000000..451911a
--- /dev/null
@@ -0,0 +1,2 @@
+default:
+       cd .. ; make
diff --git a/src/mesa/pipe/draw/draw_clip.c b/src/mesa/pipe/draw/draw_clip.c
new file mode 100644 (file)
index 0000000..f8bacf8
--- /dev/null
@@ -0,0 +1,463 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  Clipping stage
+ *
+ * \author  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#include "main/macros.h"
+#include "draw_private.h"
+
+
+struct clipper {
+   struct draw_stage stage;      /**< base class */
+
+   GLuint active_user_planes;
+   GLfloat (*plane)[4];
+};
+
+
+/* This is a bit confusing:
+ */
+static INLINE struct clipper *clipper_stage( struct draw_stage *stage )
+{
+   return (struct clipper *)stage;
+}
+
+
+#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
+
+
+/* All attributes are float[4], so this is easy:
+ */
+static void interp_attr( GLfloat *fdst,
+                        GLfloat t,
+                        const GLfloat *fin,
+                        const GLfloat *fout )
+{  
+   fdst[0] = LINTERP( t, fout[0], fin[0] );
+   fdst[1] = LINTERP( t, fout[1], fin[1] );
+   fdst[2] = LINTERP( t, fout[2], fin[2] );
+   fdst[3] = LINTERP( t, fout[3], fin[3] );
+}
+
+
+
+
+/* Interpolate between two vertices to produce a third.  
+ */
+static void interp( const struct clipper *clip,
+                   struct vertex_header *dst,
+                   GLfloat t,
+                   const struct vertex_header *out, 
+                   const struct vertex_header *in )
+{
+   const GLuint nr_attrs = clip->stage.draw->nr_attrs;
+   GLuint j;
+
+   /* Vertex header.
+    */
+   {
+      dst->clipmask = 0;
+      dst->edgeflag = 0;
+      dst->pad = 0;
+   }
+
+   /* Clip coordinates:  interpolate normally
+    */
+   {
+      interp_attr(dst->clip, t, in->clip, out->clip);
+   }
+
+   /* Do the projective divide and insert window coordinates:
+    */
+   {
+      const GLfloat *pos = dst->clip;
+      const GLfloat *scale = clip->stage.draw->viewport.scale;
+      const GLfloat *trans = clip->stage.draw->viewport.translate;
+      const GLfloat oow = 1.0 / pos[3];
+
+      dst->data[0][0] = pos[0] * oow * scale[0] + trans[0];
+      dst->data[0][1] = pos[1] * oow * scale[1] + trans[1];
+      dst->data[0][2] = pos[2] * oow * scale[2] + trans[2];
+      dst->data[0][3] = oow;
+   }
+
+   /* Other attributes
+    * Note: start at 1 to skip winpos (data[0]) since we just computed
+    * it above.
+    * Subtract two from nr_attrs since the first two attribs (always 
+    * VF_ATTRIB_VERTEX_HEADER and VF_ATTRIB_CLIP_POS, see
+    * draw_set_vertex_attributes()) are in the vertex_header struct,
+    * not in the data[] array.
+    */
+   for (j = 1; j < nr_attrs - 2; j++) {
+      interp_attr(dst->data[j], t, in->data[j], out->data[j]);
+   }
+}
+
+
+#define CLIP_USER_BIT    0x40
+#define CLIP_CULL_BIT    0x80
+
+
+static INLINE GLfloat dot4( const GLfloat *a,
+                           const GLfloat *b )
+{
+   GLfloat result = (a[0]*b[0] +
+                    a[1]*b[1] +
+                    a[2]*b[2] +
+                    a[3]*b[3]);
+
+   return result;
+}
+
+
+#if 0   
+static INLINE void do_tri( struct draw_stage *next,
+                          struct prim_header *header )
+{
+   GLuint i;
+   for (i = 0; i < 3; i++) {
+      GLfloat *ndc = header->v[i]->data[0];
+      _mesa_printf("ndc %f %f %f\n", ndc[0], ndc[1], ndc[2]);
+      assert(ndc[0] >= -1 && ndc[0] <= 641);
+      assert(ndc[1] >= 30 && ndc[1] <= 481);
+   }
+   _mesa_printf("\n");
+   next->tri(next, header);
+}
+#endif
+
+
+static void emit_poly( struct draw_stage *stage,
+                      struct vertex_header **inlist,
+                      GLuint n )
+{
+   struct prim_header header;
+   GLuint i;
+
+   for (i = 2; i < n; i++) {
+      header.v[0] = inlist[0];
+      header.v[1] = inlist[i-1];
+      header.v[2] = inlist[i];
+       
+      {
+        GLuint tmp0 = header.v[0]->edgeflag;
+        GLuint tmp2 = header.v[2]->edgeflag;
+
+        if (i != 2)   header.v[0]->edgeflag = 0;
+        if (i != n-1) header.v[2]->edgeflag = 0;
+
+        stage->next->tri( stage->next, &header );
+
+        header.v[0]->edgeflag = tmp0;
+        header.v[2]->edgeflag = tmp2;
+      }
+   }
+}
+
+
+#if 0
+static void emit_poly( struct draw_stage *stage )
+{
+   GLuint i;
+
+   for (i = 2; i < n; i++) {
+      header->v[0] = inlist[0];
+      header->v[1] = inlist[i-1];
+      header->v[2] = inlist[i];
+        
+      stage->next->tri( stage->next, header );
+   }
+}
+#endif
+
+
+/* Clip a triangle against the viewport and user clip planes.
+ */
+static void
+do_clip_tri( struct draw_stage *stage, 
+            struct prim_header *header,
+            GLuint clipmask )
+{
+   struct clipper *clipper = clipper_stage( stage );
+   struct vertex_header *a[MAX_CLIPPED_VERTICES];
+   struct vertex_header *b[MAX_CLIPPED_VERTICES];
+   struct vertex_header **inlist = a;
+   struct vertex_header **outlist = b;
+   GLuint tmpnr = 0;
+   GLuint n = 3;
+   GLuint i;
+
+   inlist[0] = header->v[0];
+   inlist[1] = header->v[1];
+   inlist[2] = header->v[2];
+
+   /* XXX: Note stupid hack to deal with tnl's 8-bit clipmask.  Remove
+    * this once we correctly use 16bit masks for userclip planes.
+    */
+   clipmask &= ~CLIP_CULL_BIT;
+   if (clipmask & CLIP_USER_BIT) {
+      clipmask &= ~CLIP_USER_BIT;
+      clipmask |= clipper->active_user_planes;
+   }
+
+   while (clipmask && n >= 3) {
+      GLuint plane_idx = ffs(clipmask)-1;
+      const GLfloat *plane = clipper->plane[plane_idx];
+      struct vertex_header *vert_prev = inlist[0];
+      GLfloat dp_prev = dot4( vert_prev->clip, plane );
+      GLuint outcount = 0;
+
+      clipmask &= ~(1<<plane_idx);
+
+      inlist[n] = inlist[0]; /* prevent rotation of vertices */
+
+      for (i = 1; i <= n; i++) {
+        struct vertex_header *vert = inlist[i];
+
+        GLfloat dp = dot4( vert->clip, plane );
+
+        if (!IS_NEGATIVE(dp_prev)) {
+           outlist[outcount++] = vert_prev;
+        }
+
+        if (DIFFERENT_SIGNS(dp, dp_prev)) {
+           struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++];
+           outlist[outcount++] = new_vert;
+
+           if (IS_NEGATIVE(dp)) {
+              /* Going out of bounds.  Avoid division by zero as we
+               * know dp != dp_prev from DIFFERENT_SIGNS, above.
+               */
+              GLfloat t = dp / (dp - dp_prev);
+              interp( clipper, new_vert, t, vert, vert_prev );
+              
+              /* Force edgeflag true in this case:
+               */
+              new_vert->edgeflag = 1;
+           } else {
+              /* Coming back in.
+               */
+              GLfloat t = dp_prev / (dp_prev - dp);
+              interp( clipper, new_vert, t, vert_prev, vert );
+
+              /* Copy starting vert's edgeflag:
+               */
+              new_vert->edgeflag = vert_prev->edgeflag;
+           }
+        }
+
+        vert_prev = vert;
+        dp_prev = dp;
+      }
+
+      {
+        struct vertex_header **tmp = inlist;
+        inlist = outlist;
+        outlist = tmp;
+        n = outcount;
+      }
+   }
+
+   /* Emit the polygon as triangles to the setup stage:
+    */
+   if (n >= 3)
+      emit_poly( stage, inlist, n );
+}
+
+
+/* Clip a line against the viewport and user clip planes.
+ */
+static void
+do_clip_line( struct draw_stage *stage,
+             struct prim_header *header,
+             GLuint clipmask )
+{
+   const struct clipper *clipper = clipper_stage( stage );
+   struct vertex_header *v0 = header->v[0];
+   struct vertex_header *v1 = header->v[1];
+   const GLfloat *pos0 = v0->clip;
+   const GLfloat *pos1 = v1->clip;
+   GLfloat t0 = 0;
+   GLfloat t1 = 0;
+   struct prim_header newprim;
+
+   /* XXX: Note stupid hack to deal with tnl's 8-bit clipmask.  Remove
+    * this once we correctly use 16bit masks for userclip planes.
+    */
+   clipmask &= ~CLIP_CULL_BIT;
+   if (clipmask & CLIP_USER_BIT) {
+      clipmask &= ~CLIP_USER_BIT;
+      clipmask |= clipper->active_user_planes;
+   }
+
+   while (clipmask) {
+      const GLuint plane_idx = ffs(clipmask)-1;
+      const GLfloat *plane = clipper->plane[plane_idx];
+      const GLfloat dp0 = dot4( pos0, plane );
+      const GLfloat dp1 = dot4( pos1, plane );
+
+      if (dp1 < 0) {
+        GLfloat t = dp1 / (dp1 - dp0);
+         t1 = MAX2(t1, t);
+      } 
+
+      if (dp0 < 0) {
+        GLfloat t = dp0 / (dp0 - dp1);
+         t0 = MAX2(t0, t);
+      }
+
+      if (t0 + t1 >= 1.0)
+        return; /* discard */
+
+      clipmask &= ~(1 << plane_idx);  /* turn off this plane's bit */
+   }
+
+   if (v0->clipmask) {
+      interp( clipper, stage->tmp[0], t0, v0, v1 );
+      newprim.v[0] = stage->tmp[0];
+   }
+   else {
+      newprim.v[0] = v0;
+   }
+
+   if (v1->clipmask) {
+      interp( clipper, stage->tmp[1], t1, v1, v0 );
+      newprim.v[1] = stage->tmp[1];
+   }
+   else {
+      newprim.v[1] = v1;
+   }
+
+   stage->next->line( stage->next, &newprim );
+}
+
+
+static void clip_begin( struct draw_stage *stage )
+{
+   struct clipper *clipper = clipper_stage(stage);
+   GLuint nr = stage->draw->nr_planes;
+
+   /* sanity checks.  If these fail, review the clip/interp code! */
+   assert(stage->draw->nr_attrs >= 3);
+   assert(stage->draw->attrs[0].attrib == VF_ATTRIB_VERTEX_HEADER);
+   assert(stage->draw->attrs[1].attrib == VF_ATTRIB_CLIP_POS);
+
+   /* Hacky bitmask to use when we hit CLIP_USER_BIT:
+    */   
+   clipper->active_user_planes = ((1<<nr)-1) & ~((1<<6)-1);
+
+   stage->next->begin( stage->next );
+}
+
+
+static void
+clip_point( struct draw_stage *stage, 
+           struct prim_header *header )
+{
+   if (header->v[0]->clipmask == 0) 
+      stage->next->point( stage->next, header );
+}
+
+
+static void
+clip_line( struct draw_stage *stage,
+          struct prim_header *header )
+{
+   GLuint clipmask = (header->v[0]->clipmask | 
+                     header->v[1]->clipmask);
+   
+   if (clipmask == 0) {
+      /* no clipping needed */
+      stage->next->line( stage->next, header );
+   }
+   else if ((header->v[0]->clipmask & 
+            header->v[1]->clipmask) == 0) {
+      do_clip_line(stage, header, clipmask);
+   }
+}
+
+
+static void
+clip_tri( struct draw_stage *stage,
+         struct prim_header *header )
+{
+   GLuint clipmask = (header->v[0]->clipmask | 
+                     header->v[1]->clipmask | 
+                     header->v[2]->clipmask);
+   
+   if (clipmask == 0) {
+      /* no clipping needed */
+      stage->next->tri( stage->next, header );
+   }
+   else if ((header->v[0]->clipmask & 
+            header->v[1]->clipmask & 
+            header->v[2]->clipmask) == 0) {
+      do_clip_tri(stage, header, clipmask);
+   }
+}
+
+
+static void clip_end( struct draw_stage *stage )
+{
+   stage->next->end( stage->next );
+}
+
+
+static void clip_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+/**
+ * Allocate a new clipper stage.
+ * \return pointer to new stage object
+ */
+struct draw_stage *draw_clip_stage( struct draw_context *draw )
+{
+   struct clipper *clipper = CALLOC_STRUCT(clipper);
+
+   draw_alloc_tmps( &clipper->stage, MAX_CLIPPED_VERTICES );
+
+   clipper->stage.draw = draw;
+   clipper->stage.begin = clip_begin;
+   clipper->stage.point = clip_point;
+   clipper->stage.line = clip_line;
+   clipper->stage.tri = clip_tri;
+   clipper->stage.end = clip_end;
+   clipper->stage.reset_stipple_counter = clip_reset_stipple_counter;
+
+   clipper->plane = draw->plane;
+
+   return &clipper->stage;
+}
diff --git a/src/mesa/pipe/draw/draw_context.c b/src/mesa/pipe/draw/draw_context.c
new file mode 100644 (file)
index 0000000..a97f488
--- /dev/null
@@ -0,0 +1,183 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "imports.h"
+#include "macros.h"
+
+#include "draw_context.h"
+#include "draw_private.h"
+
+
+struct draw_context *draw_create( void )
+{
+   struct draw_context *draw = CALLOC_STRUCT( draw_context );
+
+   /* create pipeline stages */
+   draw->pipeline.unfilled  = draw_unfilled_stage( draw );
+   draw->pipeline.twoside   = draw_twoside_stage( draw );
+   draw->pipeline.offset    = draw_offset_stage( draw );
+   draw->pipeline.clip      = draw_clip_stage( draw );
+   draw->pipeline.flatshade = draw_flatshade_stage( draw );
+   draw->pipeline.cull      = draw_cull_stage( draw );
+
+   ASSIGN_4V( draw->plane[0], -1,  0,  0, 1 );
+   ASSIGN_4V( draw->plane[1],  1,  0,  0, 1 );
+   ASSIGN_4V( draw->plane[2],  0, -1,  0, 1 );
+   ASSIGN_4V( draw->plane[3],  0,  1,  0, 1 );
+   ASSIGN_4V( draw->plane[4],  0,  0,  1, 1 ); /* yes these are correct */
+   ASSIGN_4V( draw->plane[5],  0,  0, -1, 1 ); /* mesa's a bit wonky */
+   draw->nr_planes = 6;
+
+   draw->vf = vf_create( GL_TRUE );
+
+   return draw;
+}
+
+
+void draw_destroy( struct draw_context *draw )
+{
+   if (draw->header.storage)
+      ALIGN_FREE( draw->header.storage );
+
+   vf_destroy( draw->vf );
+
+   FREE( draw );
+}
+
+
+/**
+ * Rebuild the rendering pipeline.
+ */
+static void validate_pipeline( struct draw_context *draw )
+{
+   struct draw_stage *next = draw->pipeline.setup;
+
+   /*
+    * NOTE: we build up the pipeline in end-to-start order.
+    *
+    * TODO: make the current primitive part of the state and build
+    * shorter pipelines for lines & points.
+    */
+
+   if (draw->setup.fill_cw != PIPE_POLYGON_MODE_FILL ||
+       draw->setup.fill_ccw != PIPE_POLYGON_MODE_FILL) {
+      draw->pipeline.unfilled->next = next;
+      next = draw->pipeline.unfilled;
+   }
+        
+   if (draw->setup.offset_cw ||
+       draw->setup.offset_ccw) {
+      draw->pipeline.offset->next = next;
+      next = draw->pipeline.offset;
+   }
+
+   if (draw->setup.light_twoside) {
+      draw->pipeline.twoside->next = next;
+      next = draw->pipeline.twoside;
+   }
+
+   /* Always run the cull stage as we calculate determinant there
+    * also.  Fix this..
+    */
+   {
+      draw->pipeline.cull->next = next;
+      next = draw->pipeline.cull;
+   }
+
+   /* Clip stage
+    */
+   {
+      draw->pipeline.clip->next = next;
+      next = draw->pipeline.clip;
+   }
+
+   /* Do software flatshading prior to clipping.  XXX: should only do
+    * this for clipped primitives, ie it is a part of the clip
+    * routine.
+    */
+   if (draw->setup.flatshade) {
+      draw->pipeline.flatshade->next = next;
+      next = draw->pipeline.flatshade;
+   }
+   
+   draw->pipeline.first = next;
+}
+
+
+/**
+ * Register new primitive setup/rendering state.
+ * This causes the drawing pipeline to be rebuilt.
+ */
+void draw_set_setup_state( struct draw_context *draw,
+                           const struct pipe_setup_state *setup )
+{
+   memcpy( &draw->setup, setup, sizeof(*setup) );
+   validate_pipeline( draw );
+}
+
+
+/** 
+ * Plug in the primitive rendering/rasterization stage.
+ * This is provided by the device driver.
+ */
+void draw_set_setup_stage( struct draw_context *draw,
+                           struct draw_stage *stage )
+{
+   draw->pipeline.setup = stage;
+}
+
+
+/**
+ * Set the draw module's clipping state.
+ */
+void draw_set_clip_state( struct draw_context *draw,
+                          const struct pipe_clip_state *clip )
+{
+   memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0]));
+   draw->nr_planes = 6 + clip->nr;
+}
+
+
+/**
+ * Set the draw module's viewport state.
+ */
+void draw_set_viewport_state( struct draw_context *draw,
+                              const struct pipe_viewport_state *viewport )
+{
+   draw->viewport = *viewport; /* struct copy */
+
+   vf_set_vp_scale_translate( draw->vf, viewport->scale, viewport->translate );
+
+   /* Using tnl/ and vf/ modules is temporary while getting started.
+    * Full pipe will have vertex shader, vertex fetch of its own.
+    */
+}
diff --git a/src/mesa/pipe/draw/draw_context.h b/src/mesa/pipe/draw/draw_context.h
new file mode 100644 (file)
index 0000000..c298d4f
--- /dev/null
@@ -0,0 +1,74 @@
+
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  Public interface into the drawing module.
+ */
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#ifndef DRAW_CONTEXT_H
+#define DRAW_CONTEXT_H
+
+
+#include "glheader.h"
+#include "pipe/p_state.h"
+
+
+struct vertex_buffer;
+struct draw_context;
+struct draw_stage;
+
+
+struct draw_context *draw_create( void );
+
+void draw_destroy( struct draw_context *draw );
+
+void draw_set_viewport_state( struct draw_context *draw,
+                              const struct pipe_viewport_state *viewport );
+
+void draw_set_clip_state( struct draw_context *pipe,
+                          const struct pipe_clip_state *clip );
+
+void draw_set_setup_state( struct draw_context *draw,
+                           const struct pipe_setup_state *setup );
+
+void draw_set_setup_stage( struct draw_context *draw,
+                           struct draw_stage *stage );
+
+void draw_set_vertex_attributes( struct draw_context *draw,
+                                const GLuint *attrs,
+                                GLuint nr_attrs );
+
+void draw_vb(struct draw_context *draw,
+            struct vertex_buffer *VB );
+
+
+#endif /* DRAW_CONTEXT_H */
diff --git a/src/mesa/pipe/draw/draw_cull.c b/src/mesa/pipe/draw/draw_cull.c
new file mode 100644 (file)
index 0000000..8b2ac5e
--- /dev/null
@@ -0,0 +1,138 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  Drawing stage for polygon culling
+ */
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#include "main/imports.h"
+#include "pipe/p_defines.h"
+#include "draw_private.h"
+
+
+struct cull_stage {
+   struct draw_stage stage;
+   GLuint winding;  /**< which winding(s) to cull (one of PIPE_WINDING_x) */
+};
+
+
+static INLINE struct cull_stage *cull_stage( struct draw_stage *stage )
+{
+   return (struct cull_stage *)stage;
+}
+
+
+static void cull_begin( struct draw_stage *stage )
+{
+   struct cull_stage *cull = cull_stage(stage);
+
+   cull->winding = stage->draw->setup.cull_mode;
+
+   stage->next->begin( stage->next );
+}
+
+
+static void cull_tri( struct draw_stage *stage,
+                     struct prim_header *header )
+{
+   /* Window coords: */
+   const GLfloat *v0 = header->v[0]->data[0];
+   const GLfloat *v1 = header->v[1]->data[0];
+   const GLfloat *v2 = header->v[2]->data[0];
+
+   /* edge vectors e = v0 - v2, f = v1 - v2 */
+   GLfloat ex = v0[0] - v2[0];
+   GLfloat ey = v0[1] - v2[1];
+   GLfloat fx = v1[0] - v2[0];
+   GLfloat fy = v1[1] - v2[1];
+   
+   /* det = cross(e,f).z */
+   header->det = ex * fy - ey * fx;
+
+   if (header->det != 0) {
+      /* if (det > 0 then Z points toward camera and triangle is 
+       * counter-clockwise winding.
+       */
+      GLuint winding = (header->det > 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW;
+
+      if ((winding & cull_stage(stage)->winding) == 0) {
+         /* triangle is not culled, pass to next stage */
+        stage->next->tri( stage->next, header );
+      }
+   }
+}
+
+
+static void cull_line( struct draw_stage *stage,
+                      struct prim_header *header )
+{
+   stage->next->line( stage->next, header );
+}
+
+
+static void cull_point( struct draw_stage *stage,
+                       struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+
+static void cull_end( struct draw_stage *stage )
+{
+   stage->next->end( stage->next );
+}
+
+
+static void cull_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+/**
+ * Create a new polygon culling stage.
+ */
+struct draw_stage *draw_cull_stage( struct draw_context *draw )
+{
+   struct cull_stage *cull = CALLOC_STRUCT(cull_stage);
+
+   draw_alloc_tmps( &cull->stage, 0 );
+
+   cull->stage.draw = draw;
+   cull->stage.next = NULL;
+   cull->stage.begin = cull_begin;
+   cull->stage.point = cull_point;
+   cull->stage.line = cull_line;
+   cull->stage.tri = cull_tri;
+   cull->stage.end = cull_end;
+   cull->stage.reset_stipple_counter = cull_reset_stipple_counter;
+
+   return &cull->stage;
+}
diff --git a/src/mesa/pipe/draw/draw_flatshade.c b/src/mesa/pipe/draw/draw_flatshade.c
new file mode 100644 (file)
index 0000000..cf5e762
--- /dev/null
@@ -0,0 +1,162 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "main/imports.h"
+#include "draw_private.h"
+
+
+struct flatshade_stage {
+   struct draw_stage stage;
+
+   const GLuint *lookup;
+};
+
+
+
+static INLINE struct flatshade_stage *flatshade_stage( struct draw_stage *stage )
+{
+   return (struct flatshade_stage *)stage;
+}
+
+
+static void flatshade_begin( struct draw_stage *stage )
+{
+   stage->next->begin( stage->next );
+}
+
+
+
+static INLINE void copy_attr( GLuint attr,
+                             struct vertex_header *dst, 
+                             const struct vertex_header *src )
+{
+   if (attr) {
+      memcpy( dst->data[attr],
+             src->data[attr],
+             sizeof(src->data[0]) );
+   }
+}
+
+
+static INLINE void copy_colors( struct draw_stage *stage, 
+                                struct vertex_header *dst, 
+                                const struct vertex_header *src )
+{
+   const struct flatshade_stage *flatshade = flatshade_stage(stage);
+   const GLuint *lookup = flatshade->lookup;
+
+   copy_attr( lookup[VF_ATTRIB_COLOR0], dst, src );
+   copy_attr( lookup[VF_ATTRIB_COLOR1], dst, src );
+   copy_attr( lookup[VF_ATTRIB_BFC0], dst, src );
+   copy_attr( lookup[VF_ATTRIB_BFC1], dst, src );
+}
+
+
+/**
+ * Flatshade tri.  Required for clipping and when unfilled tris are
+ * active, otherwise handled by hardware.
+ */
+static void flatshade_tri( struct draw_stage *stage,
+                          struct prim_header *header )
+{
+   struct prim_header tmp;
+
+   tmp.det = header->det;
+   tmp.v[0] = dup_vert(stage, header->v[0], 0);
+   tmp.v[1] = dup_vert(stage, header->v[1], 1);
+   tmp.v[2] = header->v[2];
+
+   copy_colors(stage, tmp.v[0], tmp.v[2]);
+   copy_colors(stage, tmp.v[1], tmp.v[2]);
+   
+   stage->next->tri( stage->next, &tmp );
+}
+
+
+/**
+ * Flatshade line.  Required for clipping.
+ */
+static void flatshade_line( struct draw_stage *stage,
+                           struct prim_header *header )
+{
+   struct prim_header tmp;
+
+   tmp.v[0] = dup_vert(stage, header->v[0], 0);
+   tmp.v[1] = header->v[1];
+
+   copy_colors(stage, tmp.v[0], tmp.v[1]);
+   
+   stage->next->line( stage->next, &tmp );
+}
+
+
+static void flatshade_point( struct draw_stage *stage,
+                             struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+
+static void flatshade_end( struct draw_stage *stage )
+{
+   stage->next->end( stage->next );
+}
+
+
+static void flatshade_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+/**
+ * Create flatshading drawing stage.
+ */
+struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
+{
+   struct flatshade_stage *flatshade = CALLOC_STRUCT(flatshade_stage);
+
+   draw_alloc_tmps( &flatshade->stage, 2 );
+
+   flatshade->stage.draw = draw;
+   flatshade->stage.next = NULL;
+   flatshade->stage.begin = flatshade_begin;
+   flatshade->stage.point = flatshade_point;
+   flatshade->stage.line = flatshade_line;
+   flatshade->stage.tri = flatshade_tri;
+   flatshade->stage.end = flatshade_end;
+   flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;
+
+   flatshade->lookup = draw->vf_attr_to_slot;
+
+   return &flatshade->stage;
+}
+
+
diff --git a/src/mesa/pipe/draw/draw_offset.c b/src/mesa/pipe/draw/draw_offset.c
new file mode 100644 (file)
index 0000000..9f66566
--- /dev/null
@@ -0,0 +1,173 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  polygon offset state
+ *
+ * \author  Keith Whitwell <keith@tungstengraphics.com>
+ * \author  Brian Paul
+ */
+
+#include "main/imports.h"
+#include "main/macros.h"
+#include "draw_private.h"
+
+
+
+struct offset_stage {
+   struct draw_stage stage;
+
+   GLfloat scale;
+   GLfloat units;
+};
+
+
+
+static INLINE struct offset_stage *offset_stage( struct draw_stage *stage )
+{
+   return (struct offset_stage *) stage;
+}
+
+
+static void offset_begin( struct draw_stage *stage )
+{
+   struct offset_stage *offset = offset_stage(stage);
+   GLfloat mrd = 1.0 / 65535.0; /* XXX this depends on depthbuffer bits! */
+
+   offset->units = stage->draw->setup.offset_units * mrd;
+   offset->scale = stage->draw->setup.offset_scale;
+
+   stage->next->begin( stage->next );
+}
+
+
+/**
+ * Offset tri Z.  Some hardware can handle this, but not usually when
+ * doing unfilled rendering.
+ */
+static void do_offset_tri( struct draw_stage *stage,
+                          struct prim_header *header )
+{
+   struct offset_stage *offset = offset_stage(stage);   
+   GLfloat inv_det = 1.0 / header->det;
+
+   /* Window coords:
+    */
+   GLfloat *v0 = header->v[0]->data[0];
+   GLfloat *v1 = header->v[1]->data[0];
+   GLfloat *v2 = header->v[2]->data[0];
+
+   /* edge vectors e = v0 - v2, f = v1 - v2 */
+   GLfloat ex = v0[0] - v2[0];
+   GLfloat ey = v0[1] - v2[1];
+   GLfloat ez = v0[2] - v2[2];
+   GLfloat fx = v1[0] - v2[0];
+   GLfloat fy = v1[1] - v2[1];
+   GLfloat fz = v1[2] - v2[2];
+
+   /* (a,b) = cross(e,f).xy */
+   GLfloat a = ey*fz - ez*fy;
+   GLfloat b = ez*fx - ex*fz;
+
+   GLfloat dzdx = FABSF(a * inv_det);
+   GLfloat dzdy = FABSF(b * inv_det);
+
+   GLfloat zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale;
+
+   /*
+    * Note: we're applying the offset and clamping per-vertex.
+    * Ideally, the offset is applied per-fragment prior to fragment shading.
+    */
+   v0[2] = CLAMP(v0[2] + zoffset, 0.0, 1.0);
+   v1[2] = CLAMP(v1[2] + zoffset, 0.0, 1.0);
+   v2[2] = CLAMP(v2[2] + zoffset, 0.0, 1.0);
+
+   stage->next->tri( stage->next, header );
+}
+
+
+static void offset_tri( struct draw_stage *stage,
+                       struct prim_header *header )
+{
+   struct prim_header tmp;
+
+   tmp.det = header->det;
+   tmp.v[0] = dup_vert(stage, header->v[0], 0);
+   tmp.v[1] = dup_vert(stage, header->v[1], 1);
+   tmp.v[2] = dup_vert(stage, header->v[2], 2);
+
+   do_offset_tri( stage, &tmp );
+}
+
+
+
+static void offset_line( struct draw_stage *stage,
+                      struct prim_header *header )
+{
+   stage->next->line( stage->next, header );
+}
+
+
+static void offset_point( struct draw_stage *stage,
+                       struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+
+static void offset_end( struct draw_stage *stage )
+{
+   stage->next->end( stage->next );
+}
+
+
+static void offset_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+/**
+ * Create polygon offset drawing stage.
+ */
+struct draw_stage *draw_offset_stage( struct draw_context *draw )
+{
+   struct offset_stage *offset = CALLOC_STRUCT(offset_stage);
+
+   draw_alloc_tmps( &offset->stage, 3 );
+
+   offset->stage.draw = draw;
+   offset->stage.next = NULL;
+   offset->stage.begin = offset_begin;
+   offset->stage.point = offset_point;
+   offset->stage.line = offset_line;
+   offset->stage.tri = offset_tri;
+   offset->stage.end = offset_end;
+   offset->stage.reset_stipple_counter = offset_reset_stipple_counter;
+
+   return &offset->stage;
+}
diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h
new file mode 100644 (file)
index 0000000..3dfaa05
--- /dev/null
@@ -0,0 +1,184 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/**
+ * Private data structures, etc for the draw module.
+ */
+
+
+/**
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Brian Paul
+ */
+
+
+#ifndef DRAW_PRIVATE_H
+#define DRAW_PRIVATE_H
+
+
+#include "main/glheader.h"
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "vf/vf.h"
+
+
+/**
+ * Basic vertex info.
+ * Carry some useful information around with the vertices in the prim pipe.  
+ */
+struct vertex_header {
+   GLuint clipmask:12;
+   GLuint edgeflag:1;
+   GLuint pad:19;
+
+   GLfloat clip[4];
+
+   GLfloat data[][4];          /* Note variable size */
+};
+
+
+/**
+ * Basic info for a point/line/triangle primitive.
+ */
+struct prim_header {
+   GLfloat det;                 /**< front/back face determinant */
+   struct vertex_header *v[3];  /**< 1 to 3 vertex pointers */
+};
+
+
+
+struct draw_context;
+
+/**
+ * Base class for all primitive drawing stages.
+ */
+struct draw_stage
+{
+   struct draw_context *draw;   /**< parent context */
+
+   struct draw_stage *next;     /**< next stage in pipeline */
+
+   struct vertex_header **tmp;
+   GLuint nr_tmps;
+
+   void (*begin)( struct draw_stage * );
+
+   void (*point)( struct draw_stage *,
+                 struct prim_header * );
+
+   void (*line)( struct draw_stage *,
+                struct prim_header * );
+
+   void (*tri)( struct draw_stage *,
+               struct prim_header * );
+   
+   void (*end)( struct draw_stage * );
+
+   void (*reset_stipple_counter)( struct draw_stage * );
+};
+
+
+/**
+ * Private context for the drawing module.
+ */
+struct draw_context
+{
+   struct {
+      struct draw_stage *first;  /**< one of the following */
+
+      /* stages (in logical order) */
+      struct draw_stage *flatshade;
+      struct draw_stage *clip;
+      struct draw_stage *cull;
+      struct draw_stage *twoside;
+      struct draw_stage *offset;
+      struct draw_stage *unfilled;
+      struct draw_stage *setup;  /* aka render/rasterize */
+   } pipeline;
+
+   /* pipe state that we need: */
+   struct pipe_setup_state setup;
+   struct pipe_viewport_state viewport;
+
+   /* Clip derived state:
+    */
+   GLfloat plane[12][4];
+   GLuint nr_planes;
+
+   GLuint vf_attr_to_slot[PIPE_ATTRIB_MAX];
+
+   struct vf_attr_map attrs[VF_ATTRIB_MAX];
+   GLuint nr_attrs;
+   GLuint vertex_size;       /**< in bytes */
+   struct vertex_fetch *vf;
+
+   GLubyte *verts;
+   GLuint nr_vertices;
+   GLboolean in_vb;
+
+   GLenum prim;   /**< GL_POINTS, GL_LINE_STRIP, GL_QUADS, etc */
+
+   /* Helper for tnl:
+    */
+   GLvector4f header;   
+};
+
+
+
+extern struct draw_stage *draw_unfilled_stage( struct draw_context *context );
+extern struct draw_stage *draw_twoside_stage( struct draw_context *context );
+extern struct draw_stage *draw_offset_stage( struct draw_context *context );
+extern struct draw_stage *draw_clip_stage( struct draw_context *context );
+extern struct draw_stage *draw_flatshade_stage( struct draw_context *context );
+extern struct draw_stage *draw_cull_stage( struct draw_context *context );
+
+
+extern void draw_free_tmps( struct draw_stage *stage );
+extern void draw_alloc_tmps( struct draw_stage *stage, GLuint nr );
+
+
+
+/**
+ * Get a writeable copy of a vertex.
+ * \param stage  drawing stage info
+ * \param vert  the vertex to copy (source)
+ * \param idx  index into stage's tmp[] array to put the copy (dest)
+ * \return  pointer to the copied vertex
+ */
+static INLINE struct vertex_header *
+dup_vert( struct draw_stage *stage,
+         const struct vertex_header *vert,
+         GLuint idx )
+{   
+   struct vertex_header *tmp = stage->tmp[idx];
+   memcpy(tmp, vert, stage->draw->vertex_size );
+   return tmp;
+}
+
+
+#endif /* DRAW_PRIVATE_H */
diff --git a/src/mesa/pipe/draw/draw_twoside.c b/src/mesa/pipe/draw/draw_twoside.c
new file mode 100644 (file)
index 0000000..fdda6b3
--- /dev/null
@@ -0,0 +1,169 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "main/imports.h"
+#include "pipe/p_defines.h"
+#include "draw_private.h"
+
+
+struct twoside_stage {
+   struct draw_stage stage;
+   GLfloat sign;         /**< +1 or -1 */
+   const GLuint *lookup;
+};
+
+
+static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage )
+{
+   return (struct twoside_stage *)stage;
+}
+
+
+static void twoside_begin( struct draw_stage *stage )
+{
+   struct twoside_stage *twoside = twoside_stage(stage);
+
+   /*
+    * We'll multiply the primitive's determinant by this sign to determine
+    * if the triangle is back-facing (negative).
+    * sign = 1 for CCW, -1 for CW
+    */
+   twoside->sign = (stage->draw->setup.front_winding == PIPE_WINDING_CCW) ? 1 : -1;
+
+   stage->next->begin( stage->next );
+}
+
+
+static INLINE void copy_color( GLuint attr_dst,
+                              GLuint attr_src,
+                              struct vertex_header *v )
+{
+   if (attr_dst && attr_src) {
+      memcpy( v->data[attr_dst],
+             v->data[attr_src],
+             sizeof(v->data[0]) );
+   }
+}
+
+
+static struct vertex_header *copy_bfc( struct twoside_stage *twoside, 
+                                      const struct vertex_header *v,
+                                      GLuint idx )
+{   
+   struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx );
+   
+   copy_color( twoside->lookup[VF_ATTRIB_COLOR0], 
+              twoside->lookup[VF_ATTRIB_BFC0],
+              tmp );
+
+   copy_color( twoside->lookup[VF_ATTRIB_COLOR1], 
+              twoside->lookup[VF_ATTRIB_BFC1],
+              tmp );
+
+   return tmp;
+}
+
+
+/* Twoside tri:
+ */
+static void twoside_tri( struct draw_stage *stage,
+                        struct prim_header *header )
+{
+   struct twoside_stage *twoside = twoside_stage(stage);
+
+   if (header->det * twoside->sign < 0.0) {
+      /* this is a back-facing triangle */
+      struct prim_header tmp;
+
+      tmp.det = header->det;
+      /* copy back colors to front color slots */
+      tmp.v[0] = copy_bfc(twoside, header->v[0], 0);
+      tmp.v[1] = copy_bfc(twoside, header->v[1], 1);
+      tmp.v[2] = copy_bfc(twoside, header->v[2], 2);
+
+      stage->next->tri( stage->next, &tmp );
+   }
+   else {
+      stage->next->tri( stage->next, header );
+   }
+}
+
+
+static void twoside_line( struct draw_stage *stage,
+                      struct prim_header *header )
+{
+   /* pass-through */
+   stage->next->line( stage->next, header );
+}
+
+
+static void twoside_point( struct draw_stage *stage,
+                       struct prim_header *header )
+{
+   /* pass-through */
+   stage->next->point( stage->next, header );
+}
+
+
+static void twoside_end( struct draw_stage *stage )
+{
+   /* pass-through */
+   stage->next->end( stage->next );
+}
+
+
+static void twoside_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+/**
+ * Create twoside pipeline stage.
+ */
+struct draw_stage *draw_twoside_stage( struct draw_context *draw )
+{
+   struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage);
+
+   draw_alloc_tmps( &twoside->stage, 3 );
+
+   twoside->stage.draw = draw;
+   twoside->stage.next = NULL;
+   twoside->stage.begin = twoside_begin;
+   twoside->stage.point = twoside_point;
+   twoside->stage.line = twoside_line;
+   twoside->stage.tri = twoside_tri;
+   twoside->stage.end = twoside_end;
+   twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter;
+
+   twoside->lookup = draw->vf_attr_to_slot;
+
+   return &twoside->stage;
+}
diff --git a/src/mesa/pipe/draw/draw_unfilled.c b/src/mesa/pipe/draw/draw_unfilled.c
new file mode 100644 (file)
index 0000000..82e8775
--- /dev/null
@@ -0,0 +1,185 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  Drawing stage for handling glPolygonMode(line/point).
+ * Convert triangles to points or lines as needed.
+ */
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "main/imports.h"
+#include "pipe/p_defines.h"
+#include "draw_private.h"
+
+
+struct unfilled_stage {
+   struct draw_stage stage;
+
+   /** [0] = front face, [1] = back face.
+    * legal values:  PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE,
+    * and PIPE_POLYGON_MODE_POINT,
+    */
+   GLuint mode[2];
+};
+
+
+static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage )
+{
+   return (struct unfilled_stage *)stage;
+}
+
+
+static void unfilled_begin( struct draw_stage *stage )
+{
+   struct unfilled_stage *unfilled = unfilled_stage(stage);
+
+   unfilled->mode[0] = stage->draw->setup.fill_ccw; /* front */
+   unfilled->mode[1] = stage->draw->setup.fill_cw;  /* back */
+
+   stage->next->begin( stage->next );
+}
+
+static void point( struct draw_stage *stage,
+                  struct vertex_header *v0 )
+{
+   struct prim_header tmp;
+   tmp.v[0] = v0;
+   stage->next->point( stage->next, &tmp );
+}
+
+static void line( struct draw_stage *stage,
+                 struct vertex_header *v0,
+                 struct vertex_header *v1 )
+{
+   struct prim_header tmp;
+   tmp.v[0] = v0;
+   tmp.v[1] = v1;
+   stage->next->line( stage->next, &tmp );
+}
+
+
+static void points( struct draw_stage *stage,
+                   struct prim_header *header )
+{
+   struct vertex_header *v0 = header->v[0];
+   struct vertex_header *v1 = header->v[1];
+   struct vertex_header *v2 = header->v[2];
+
+   if (v0->edgeflag) point( stage, v0 );
+   if (v1->edgeflag) point( stage, v1 );
+   if (v2->edgeflag) point( stage, v2 );
+}
+
+
+static void lines( struct draw_stage *stage,
+                  struct prim_header *header )
+{
+   struct vertex_header *v0 = header->v[0];
+   struct vertex_header *v1 = header->v[1];
+   struct vertex_header *v2 = header->v[2];
+
+   if (v0->edgeflag) line( stage, v0, v1 );
+   if (v1->edgeflag) line( stage, v1, v2 );
+   if (v2->edgeflag) line( stage, v2, v0 );
+}
+
+
+/* Unfilled tri:  
+ *
+ * Note edgeflags in the vertex struct is not sufficient as we will
+ * need to manipulate them when decomposing primitives???
+ */
+static void unfilled_tri( struct draw_stage *stage,
+                         struct prim_header *header )
+{
+   struct unfilled_stage *unfilled = unfilled_stage(stage);
+   GLuint mode = unfilled->mode[header->det > 0.0];
+  
+   switch (mode) {
+   case PIPE_POLYGON_MODE_FILL:
+      stage->next->tri( stage->next, header );
+      break;
+   case PIPE_POLYGON_MODE_LINE:
+      lines( stage, header );
+      break;
+   case PIPE_POLYGON_MODE_POINT:
+      points( stage, header );
+      break;
+   default:
+      abort();
+   }   
+}
+
+static void unfilled_line( struct draw_stage *stage,
+                           struct prim_header *header )
+{
+   stage->next->line( stage->next, header );
+}
+
+
+static void unfilled_point( struct draw_stage *stage,
+                            struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+
+static void unfilled_end( struct draw_stage *stage )
+{
+   stage->next->end( stage->next );
+}
+
+
+static void unfilled_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+/**
+ * Create unfilled triangle stage.
+ */
+struct draw_stage *draw_unfilled_stage( struct draw_context *draw )
+{
+   struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage);
+
+   draw_alloc_tmps( &unfilled->stage, 0 );
+
+   unfilled->stage.draw = draw;
+   unfilled->stage.next = NULL;
+   unfilled->stage.tmp = NULL;
+   unfilled->stage.begin = unfilled_begin;
+   unfilled->stage.point = unfilled_point;
+   unfilled->stage.line = unfilled_line;
+   unfilled->stage.tri = unfilled_tri;
+   unfilled->stage.end = unfilled_end;
+   unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter;
+
+   return &unfilled->stage;
+}
diff --git a/src/mesa/pipe/draw/draw_vb.c b/src/mesa/pipe/draw/draw_vb.c
new file mode 100644 (file)
index 0000000..ac126c5
--- /dev/null
@@ -0,0 +1,728 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "imports.h"
+#include "macros.h"
+
+#include "tnl/t_context.h"
+#include "vf/vf.h"
+
+#include "draw_private.h"
+#include "draw_context.h"
+
+
+/* This file is a temporary set of hooks to allow us to use the tnl/
+ * and vf/ modules until we have replacements in pipe.
+ */
+
+
+static struct vertex_header *get_vertex( struct draw_context *pipe,
+                                              GLuint i )
+{
+   return (struct vertex_header *)(pipe->verts + i * pipe->vertex_size);
+}
+
+
+
+static void draw_allocate_vertices( struct draw_context *draw,
+                                   GLuint nr_vertices )
+{
+   draw->nr_vertices = nr_vertices;
+   draw->verts = MALLOC( nr_vertices * draw->vertex_size );
+
+   draw->pipeline.first->begin( draw->pipeline.first );
+}
+
+static void draw_set_prim( struct draw_context *draw,
+                          GLenum prim )
+{
+   draw->prim = prim;
+
+   /* Not done yet - need to force edgeflags to 1 in strip/fan
+    * primitives.
+    */
+#if 0
+   switch (prim) {
+   case GL_TRIANGLES:
+   case GL_POLYGON:
+   case GL_QUADS:
+   case GL_QUAD_STRIP:         /* yes, we need this */
+      respect_edgeflags( pipe, GL_TRUE );
+      break;
+
+   default:
+      respect_edgeflags( pipe, GL_FALSE );
+      break;
+   }
+#endif
+}
+                         
+
+
+static void do_quad( struct draw_stage *first,
+                    struct vertex_header *v0,
+                    struct vertex_header *v1,
+                    struct vertex_header *v2,
+                    struct vertex_header *v3 )
+{
+   struct prim_header prim;
+
+   {
+      GLuint tmp = v1->edgeflag;
+      v1->edgeflag = 0;
+
+      prim.v[0] = v0;
+      prim.v[1] = v1;
+      prim.v[2] = v3;
+      first->tri( first, &prim );
+
+      v1->edgeflag = tmp;
+   }
+
+   {
+      GLuint tmp = v3->edgeflag;
+      v3->edgeflag = 0;
+
+      prim.v[0] = v1;
+      prim.v[1] = v2;
+      prim.v[2] = v3;
+      first->tri( first, &prim );
+
+      v3->edgeflag = tmp;
+   }
+}
+
+
+
+
+static void draw_indexed_prim( struct draw_context *draw,
+                              const GLuint *elts,
+                              GLuint count )
+{
+   struct draw_stage * const first = draw->pipeline.first;
+   struct prim_header prim;
+   GLuint i;
+
+   prim.det = 0;               /* valid from cull stage onwards */
+   prim.v[0] = 0;
+   prim.v[1] = 0;
+   prim.v[2] = 0;
+
+   switch (draw->prim) {
+   case GL_POINTS:
+      for (i = 0; i < count; i ++) {
+        prim.v[0] = get_vertex( draw, elts[i] );
+
+        first->point( first, &prim );
+      }
+      break;
+
+   case GL_LINES:
+      for (i = 0; i+1 < count; i += 2) {
+        prim.v[0] = get_vertex( draw, elts[i + 0] );
+        prim.v[1] = get_vertex( draw, elts[i + 1] );
+      
+         first->reset_stipple_counter( first );
+        first->line( first, &prim );
+      }
+      break;
+
+   case GL_LINE_LOOP:  
+      if (count >= 2) {
+         first->reset_stipple_counter( first );
+        for (i = 1; i < count; i++) {
+           prim.v[0] = get_vertex( draw, elts[i-1] );
+           prim.v[1] = get_vertex( draw, elts[i] );        
+           first->line( first, &prim );
+        }
+
+        prim.v[0] = get_vertex( draw, elts[count-1] );
+        prim.v[1] = get_vertex( draw, elts[0] );           
+        first->line( first, &prim );
+      }
+      break;
+
+   case GL_LINE_STRIP:
+      /* I'm guessing it will be necessary to have something like a
+       * render->reset_line_stipple() method to properly support
+       * splitting strips into primitives like this.  Alternately we
+       * could just scan ahead to find individual clipped lines and
+       * otherwise leave the strip intact - that might be better, but
+       * require more complex code here.
+       */
+      if (count >= 2) {
+         first->reset_stipple_counter( first );
+        prim.v[0] = 0;
+        prim.v[1] = get_vertex( draw, elts[0] );
+        
+        for (i = 1; i < count; i++) {
+           prim.v[0] = prim.v[1];
+           prim.v[1] = get_vertex( draw, elts[i] );
+           
+           first->line( first, &prim );
+        }
+      }
+      break;
+
+   case GL_TRIANGLES:
+      for (i = 0; i+2 < count; i += 3) {
+        prim.v[0] = get_vertex( draw, elts[i + 0] );
+        prim.v[1] = get_vertex( draw, elts[i + 1] );
+        prim.v[2] = get_vertex( draw, elts[i + 2] );
+      
+        first->tri( first, &prim );
+      }
+      break;
+
+   case GL_TRIANGLE_STRIP:
+      for (i = 0; i+2 < count; i++) {
+        if (i & 1) {
+           prim.v[0] = get_vertex( draw, elts[i + 1] );
+           prim.v[1] = get_vertex( draw, elts[i + 0] );
+           prim.v[2] = get_vertex( draw, elts[i + 2] );
+        }
+        else {
+           prim.v[0] = get_vertex( draw, elts[i + 0] );
+           prim.v[1] = get_vertex( draw, elts[i + 1] );
+           prim.v[2] = get_vertex( draw, elts[i + 2] );
+        }
+        
+        first->tri( first, &prim );
+      }
+      break;
+
+   case GL_TRIANGLE_FAN:
+      if (count >= 3) {
+        prim.v[0] = get_vertex( draw, elts[0] );
+        prim.v[1] = 0;
+        prim.v[2] = get_vertex( draw, elts[1] );
+        
+        for (i = 0; i+2 < count; i++) {
+           prim.v[1] = prim.v[2];
+           prim.v[2] = get_vertex( draw, elts[i+2] );
+      
+           first->tri( first, &prim );
+        }
+      }
+      break;
+
+   case GL_QUADS:
+      for (i = 0; i+3 < count; i += 4) {
+        do_quad( first,
+                 get_vertex( draw, elts[i + 0] ),
+                 get_vertex( draw, elts[i + 1] ),
+                 get_vertex( draw, elts[i + 2] ),
+                 get_vertex( draw, elts[i + 3] ));
+      }
+      break;
+
+   case GL_QUAD_STRIP:
+      for (i = 0; i+3 < count; i += 2) {
+        do_quad( first,
+                 get_vertex( draw, elts[i + 2] ),
+                 get_vertex( draw, elts[i + 0] ),
+                 get_vertex( draw, elts[i + 1] ),
+                 get_vertex( draw, elts[i + 3] ));
+      }
+      break;
+
+
+   case GL_POLYGON:
+      if (count >= 3) {
+         int e1save, e2save;
+        prim.v[0] = 0;
+        prim.v[1] = get_vertex( draw, elts[1] );
+        prim.v[2] = get_vertex( draw, elts[0] );
+        e2save = prim.v[2]->edgeflag;
+        
+        for (i = 0; i+2 < count; i++) {
+           prim.v[0] = prim.v[1];
+           prim.v[1] = get_vertex( draw, elts[i+2] );
+      
+            /* save v1 edge flag, and clear if not last triangle */
+            e1save = prim.v[1]->edgeflag;
+            if (i + 3 < count)
+               prim.v[1]->edgeflag = 0;
+
+            /* draw */
+           first->tri( first, &prim );
+
+            prim.v[1]->edgeflag = e1save; /* restore */
+            prim.v[2]->edgeflag = 0; /* disable edge after 1st tri */
+        }
+         prim.v[2]->edgeflag = e2save;
+      }
+      break;
+
+   default:
+      assert(0);
+      break;
+   }
+}
+
+static void draw_prim( struct draw_context *draw,
+                      GLuint start,
+                      GLuint count )
+{
+   struct draw_stage * const first = draw->pipeline.first;
+   struct prim_header prim;
+   GLuint i;
+
+//   _mesa_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count );
+
+   prim.det = 0;               /* valid from cull stage onwards */
+   prim.v[0] = 0;
+   prim.v[1] = 0;
+   prim.v[2] = 0;
+
+   switch (draw->prim) {
+   case GL_POINTS:
+      for (i = 0; i < count; i ++) {
+        prim.v[0] = get_vertex( draw, start + i );
+        first->point( first, &prim );
+      }
+      break;
+
+   case GL_LINES:
+      for (i = 0; i+1 < count; i += 2) {
+        prim.v[0] = get_vertex( draw, start + i + 0 );
+        prim.v[1] = get_vertex( draw, start + i + 1 );
+
+         first->reset_stipple_counter( first );
+        first->line( first, &prim );
+      }
+      break;
+
+   case GL_LINE_LOOP:  
+      if (count >= 2) {
+         first->reset_stipple_counter( first );
+        for (i = 1; i < count; i++) {
+           prim.v[0] = get_vertex( draw, start + i - 1 );
+           prim.v[1] = get_vertex( draw, start + i );      
+           first->line( first, &prim );
+        }
+
+        prim.v[0] = get_vertex( draw, start + count - 1 );
+        prim.v[1] = get_vertex( draw, start + 0 );         
+        first->line( first, &prim );
+      }
+      break;
+
+   case GL_LINE_STRIP:
+      if (count >= 2) {
+         first->reset_stipple_counter( first );
+        prim.v[0] = 0;
+        prim.v[1] = get_vertex( draw, start + 0 );
+        
+        for (i = 1; i < count; i++) {
+           prim.v[0] = prim.v[1];
+           prim.v[1] = get_vertex( draw, start + i );
+           
+           first->line( first, &prim );
+        }
+      }
+      break;
+
+   case GL_TRIANGLES:
+      for (i = 0; i+2 < count; i += 3) {
+        prim.v[0] = get_vertex( draw, start + i + 0 );
+        prim.v[1] = get_vertex( draw, start + i + 1 );
+        prim.v[2] = get_vertex( draw, start + i + 2 );
+      
+        first->tri( first, &prim );
+      }
+      break;
+
+   case GL_TRIANGLE_STRIP:
+      for (i = 0; i+2 < count; i++) {
+        if (i & 1) {
+           prim.v[0] = get_vertex( draw, start + i + 1 );
+           prim.v[1] = get_vertex( draw, start + i + 0 );
+           prim.v[2] = get_vertex( draw, start + i + 2 );
+        }
+        else {
+           prim.v[0] = get_vertex( draw, start + i + 0 );
+           prim.v[1] = get_vertex( draw, start + i + 1 );
+           prim.v[2] = get_vertex( draw, start + i + 2 );
+        }
+        
+        first->tri( first, &prim );
+      }
+      break;
+
+   case GL_TRIANGLE_FAN:
+      if (count >= 3) {
+        prim.v[0] = get_vertex( draw, start + 0 );
+        prim.v[1] = 0;
+        prim.v[2] = get_vertex( draw, start + 1 );
+        
+        for (i = 0; i+2 < count; i++) {
+           prim.v[1] = prim.v[2];
+           prim.v[2] = get_vertex( draw, start + i + 2 );
+      
+           first->tri( first, &prim );
+        }
+      }
+      break;
+
+
+   case GL_QUADS:
+      for (i = 0; i+3 < count; i += 4) {
+        do_quad( first,
+                 get_vertex( draw, start + i + 0 ),
+                 get_vertex( draw, start + i + 1 ),
+                 get_vertex( draw, start + i + 2 ),
+                 get_vertex( draw, start + i + 3 ));
+      }
+      break;
+
+   case GL_QUAD_STRIP:
+      for (i = 0; i+3 < count; i += 2) {
+        do_quad( first,
+                 get_vertex( draw, start + i + 2 ),
+                 get_vertex( draw, start + i + 0 ),
+                 get_vertex( draw, start + i + 1 ),
+                 get_vertex( draw, start + i + 3 ));
+      }
+      break;
+
+   case GL_POLYGON:
+      if (count >= 3) {
+         int e1save, e2save;
+        prim.v[0] = 0;
+        prim.v[1] = get_vertex( draw, start + 1 );
+        prim.v[2] = get_vertex( draw, start + 0 );
+        e2save = prim.v[2]->edgeflag;
+
+        for (i = 0; i+2 < count; i++) {
+           prim.v[0] = prim.v[1];
+           prim.v[1] = get_vertex( draw, start + i + 2 );
+
+            /* save v1 edge flag, and clear if not last triangle */
+            e1save = prim.v[1]->edgeflag;
+            if (i + 3 < count)
+               prim.v[1]->edgeflag = 0;
+
+            /* draw */
+           first->tri( first, &prim );
+
+            prim.v[1]->edgeflag = e1save; /* restore */
+            prim.v[2]->edgeflag = 0; /* disable edge after 1st tri */
+        }
+         prim.v[2]->edgeflag = e2save;
+      }
+      break;
+
+   default:
+      assert(0);
+      break;
+   }
+}
+
+
+static void draw_release_vertices( struct draw_context *draw )
+{
+   draw->pipeline.first->end( draw->pipeline.first );
+
+   FREE(draw->verts);
+   draw->verts = NULL;
+}
+
+
+struct header_dword {
+   GLuint clipmask:12;
+   GLuint edgeflag:1;
+   GLuint pad:19;
+};
+
+
+static void 
+build_vertex_headers( struct draw_context *draw,
+                     struct vertex_buffer *VB )
+{
+   if (draw->header.storage == NULL) {
+      draw->header.stride = sizeof(GLfloat);
+      draw->header.size = 1;
+      draw->header.storage = ALIGN_MALLOC( VB->Size * sizeof(GLfloat), 32 );
+      draw->header.data = draw->header.storage;
+      draw->header.count = 0;
+      draw->header.flags = VEC_SIZE_1 | VEC_MALLOC;
+   }
+
+   /* Build vertex header attribute.
+    * 
+    */
+
+   {
+      GLuint i;
+      struct header_dword *header = (struct header_dword *)draw->header.storage;
+
+      /* yes its a hack
+       */
+      assert(sizeof(*header) == sizeof(GLfloat));
+
+      draw->header.count = VB->Count;
+
+      if (VB->EdgeFlag) {
+        for (i = 0; i < VB->Count; i++) {
+           header[i].clipmask = VB->ClipMask[i];
+           header[i].edgeflag = VB->EdgeFlag[i]; 
+           header[i].pad = 0;
+        }
+      }
+      else if (VB->ClipOrMask) {
+        for (i = 0; i < VB->Count; i++) {
+           header[i].clipmask = VB->ClipMask[i];
+           header[i].edgeflag = 0; 
+           header[i].pad = 0;
+        }
+      }
+      else {
+        for (i = 0; i < VB->Count; i++) {
+           header[i].clipmask = 0;
+           header[i].edgeflag = 0; 
+           header[i].pad = 0;
+        }
+      }
+   }
+
+   VB->AttribPtr[VF_ATTRIB_VERTEX_HEADER] = &draw->header;
+}
+
+
+
+
+
+static GLuint draw_prim_info(GLenum mode, GLuint *first, GLuint *incr)
+{
+   switch (mode) {
+   case GL_POINTS:
+      *first = 1;
+      *incr = 1;
+      return 0;
+   case GL_LINES:
+      *first = 2;
+      *incr = 2;
+      return 0;
+   case GL_LINE_STRIP:
+      *first = 2;
+      *incr = 1;
+      return 0;
+   case GL_LINE_LOOP:
+      *first = 2;
+      *incr = 1;
+      return 1;
+   case GL_TRIANGLES:
+      *first = 3;
+      *incr = 3;
+      return 0;
+   case GL_TRIANGLE_STRIP:
+      *first = 3;
+      *incr = 1;
+      return 0;
+   case GL_TRIANGLE_FAN:
+   case GL_POLYGON:
+      *first = 3;
+      *incr = 1;
+      return 1;
+   case GL_QUADS:
+      *first = 4;
+      *incr = 4;
+      return 0;
+   case GL_QUAD_STRIP:
+      *first = 4;
+      *incr = 2;
+      return 0;
+   default:
+      assert(0);
+      *first = 1;
+      *incr = 1;
+      return 0;
+   }
+}
+
+
+static GLuint trim( GLuint count, GLuint first, GLuint incr )
+{
+   if (count < first)
+      return 0;
+   else
+      return count - (count - first) % incr; 
+}
+
+
+/* This is a hack & will all go away.
+ */
+void draw_vb(struct draw_context *draw,
+            struct vertex_buffer *VB )
+{
+   GLuint i;
+
+   VB->AttribPtr[VF_ATTRIB_POS] = VB->NdcPtr;
+   VB->AttribPtr[VF_ATTRIB_BFC0] = VB->ColorPtr[1];
+   VB->AttribPtr[VF_ATTRIB_BFC1] = VB->SecondaryColorPtr[1];
+   VB->AttribPtr[VF_ATTRIB_CLIP_POS] = VB->ClipPtr;
+
+   /* Build vertex headers: 
+    */
+   build_vertex_headers( draw, VB );
+
+   draw->in_vb = 1;
+
+   /* Allocate the vertices:
+    */
+   draw_allocate_vertices( draw, VB->Count );
+
+   /* Bind the vb outputs:
+    */
+   vf_set_sources( draw->vf, VB->AttribPtr, 0 );
+
+   /* Build the hardware or prim-pipe vertices: 
+    */
+   vf_emit_vertices( draw->vf, VB->Count, draw->verts );
+
+
+   for (i = 0; i < VB->PrimitiveCount; i++) {
+
+      GLenum mode = VB->Primitive[i].mode;
+      GLuint start = VB->Primitive[i].start;
+      GLuint length, first, incr;
+
+      /* Trim the primitive down to a legal size.  
+       */
+      draw_prim_info( mode, &first, &incr );
+      length = trim( VB->Primitive[i].count, first, incr );
+
+      if (!length)
+        continue;
+
+      if (draw->prim != mode) 
+        draw_set_prim( draw, mode );
+
+      if (VB->Elts) {
+        draw_indexed_prim( draw, 
+                           VB->Elts + start,
+                           length );
+      }
+      else {
+        draw_prim( draw, 
+                   start,
+                   length );
+      }         
+   }
+
+   draw_release_vertices( draw );
+   draw->verts = NULL;
+   draw->in_vb = 0;
+}
+
+
+/**
+ * Accumulate another attribute's info.
+ * Note the "- 2" factor here.  We need this because the vertex->data[]
+ * array does not include the first two attributes we emit (VERTEX_HEADER
+ * and CLIP_POS).  So, the 3rd attribute actually winds up in the 1st
+ * position of the data[] array.
+ */
+#define EMIT_ATTR( VF_ATTR, STYLE )                            \
+do {                                                           \
+   if (draw->nr_attrs >= 2)                                    \
+      draw->vf_attr_to_slot[VF_ATTR] = draw->nr_attrs - 2;     \
+   draw->attrs[draw->nr_attrs].attrib = VF_ATTR;               \
+   draw->attrs[draw->nr_attrs].format = STYLE;                 \
+   draw->nr_attrs++;                                           \
+} while (0)
+
+
+/**
+ * Tell the draw module about the layout of attributes in the vertex.
+ * We need this in order to know which vertex slot has color0, etc.
+ *
+ * \param slot_to_vf_attr  an array which maps slot indexes to vertex
+ *                         format tokens (VF_*).
+ * \param nr_attrs  the size of the slot_to_vf_attr array
+ *                  (and number of attributes)
+ */
+void draw_set_vertex_attributes( struct draw_context *draw,
+                                const GLuint *slot_to_vf_attr,
+                                GLuint nr_attrs )
+{
+   GLuint i;
+
+   memset(draw->vf_attr_to_slot, 0, sizeof(draw->vf_attr_to_slot));
+   draw->nr_attrs = 0;
+
+   /*
+    * First three attribs are always the same: header, clip pos, winpos
+    */
+   EMIT_ATTR(VF_ATTRIB_VERTEX_HEADER, EMIT_1F);
+   EMIT_ATTR(VF_ATTRIB_CLIP_POS, EMIT_4F);
+
+   assert(slot_to_vf_attr[0] == VF_ATTRIB_POS);
+   EMIT_ATTR(slot_to_vf_attr[0], EMIT_4F_VIEWPORT);
+
+   /*
+    * Remaining attribs (color, texcoords, etc)
+    */
+   for (i = 1; i < nr_attrs; i++) 
+      EMIT_ATTR(slot_to_vf_attr[i], EMIT_4F);
+
+   /* tell the vertex format module how to construct vertices for us */
+   draw->vertex_size = vf_set_vertex_attributes( draw->vf, draw->attrs,
+                                                 draw->nr_attrs, 0 );
+}
+                           
+
+#define MAX_VERTEX_SIZE ((2 + FRAG_ATTRIB_MAX) * 4 * sizeof(GLfloat))
+
+void draw_alloc_tmps( struct draw_stage *stage, GLuint nr )
+{
+   stage->nr_tmps = nr;
+
+   if (nr) {
+      GLubyte *store = MALLOC(MAX_VERTEX_SIZE * nr);
+      GLuint i;
+
+      stage->tmp = MALLOC(sizeof(struct vertex_header *) * nr);
+      
+      for (i = 0; i < nr; i++)
+        stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE);
+   }
+}
+
+void draw_free_tmps( struct draw_stage *stage )
+{
+   if (stage->tmp) {
+      FREE(stage->tmp[0]);
+      FREE(stage->tmp);
+   }
+}
diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h
new file mode 100644 (file)
index 0000000..05a175c
--- /dev/null
@@ -0,0 +1,120 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#ifndef PIPE_CONTEXT_H
+#define PIPE_CONTEXT_H
+
+#include "main/mtypes.h"
+#include "p_state.h"
+
+
+/* Kludge:
+ */
+extern struct pipe_context *softpipe_create( void );
+                                     
+/* Drawing currently kludged up via the existing tnl/ module.  
+ */
+struct vertex_buffer;
+
+
+/**
+ * Software pipeline rendering context.  Basically a collection of
+ * state setting functions, plus VBO drawing entrypoint.
+ */
+struct pipe_context {
+
+   void (*destroy)( struct pipe_context * );
+
+   /*
+    * Drawing
+    */
+   void (*draw_vb)( struct pipe_context *pipe,
+                   struct vertex_buffer *VB );
+
+   /** Clear framebuffer */
+   void (*clear)(struct pipe_context *pipe, GLboolean color, GLboolean depth,
+                 GLboolean stencil, GLboolean accum);
+
+   /** occlusion counting (XXX this may be temporary - we should probably
+    * have generic query objects with begin/end methods)
+    */
+   void (*reset_occlusion_counter)(struct pipe_context *pipe);
+   GLuint (*get_occlusion_counter)(struct pipe_context *pipe);
+
+   /*
+    * State functions
+    */
+   void (*set_alpha_test_state)( struct pipe_context *,
+                                 const struct pipe_alpha_test_state * );
+
+   void (*set_blend_state)( struct pipe_context *,
+                            const struct pipe_blend_state * );
+
+   void (*set_blend_color)( struct pipe_context *,
+                            const struct pipe_blend_color * );
+
+   void (*set_clip_state)( struct pipe_context *,
+                          const struct pipe_clip_state * );
+
+   void (*set_clear_color_state)( struct pipe_context *,
+                                  const struct pipe_clear_color_state * );
+
+   void (*set_depth_state)( struct pipe_context *,
+                              const struct pipe_depth_state * );
+
+   void (*set_framebuffer_state)( struct pipe_context *,
+                                  const struct pipe_framebuffer_state * );
+
+   void (*set_fs_state)( struct pipe_context *,
+                        const struct pipe_fs_state * );
+
+   void (*set_polygon_stipple)( struct pipe_context *,
+                               const struct pipe_poly_stipple * );
+
+   void (*set_setup_state)( struct pipe_context *,
+                           const struct pipe_setup_state * );
+
+   void (*set_scissor_state)( struct pipe_context *,
+                              const struct pipe_scissor_state * );
+
+   void (*set_stencil_state)( struct pipe_context *,
+                              const struct pipe_stencil_state * );
+
+   void (*set_sampler_state)( struct pipe_context *,
+                              GLuint unit,
+                              const struct pipe_sampler_state * );
+
+   void (*set_texture_state)( struct pipe_context *,
+                              GLuint unit,
+                              struct pipe_texture_object * );
+
+   void (*set_viewport_state)( struct pipe_context *,
+                               const struct pipe_viewport_state * );
+};
+
+
+#endif
diff --git a/src/mesa/pipe/p_defines.h b/src/mesa/pipe/p_defines.h
new file mode 100644 (file)
index 0000000..58f0175
--- /dev/null
@@ -0,0 +1,167 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#ifndef PIPE_DEFINES_H
+#define PIPE_DEFINES_H
+
+#define PIPE_BLENDFACTOR_ONE                 0x1
+#define PIPE_BLENDFACTOR_SRC_COLOR           0x2
+#define PIPE_BLENDFACTOR_SRC_ALPHA           0x3
+#define PIPE_BLENDFACTOR_DST_ALPHA           0x4
+#define PIPE_BLENDFACTOR_DST_COLOR           0x5
+#define PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE  0x6
+#define PIPE_BLENDFACTOR_CONST_COLOR         0x7
+#define PIPE_BLENDFACTOR_CONST_ALPHA         0x8
+#define PIPE_BLENDFACTOR_SRC1_COLOR          0x9
+#define PIPE_BLENDFACTOR_SRC1_ALPHA          0x0A
+#define PIPE_BLENDFACTOR_ZERO                0x11
+#define PIPE_BLENDFACTOR_INV_SRC_COLOR       0x12
+#define PIPE_BLENDFACTOR_INV_SRC_ALPHA       0x13
+#define PIPE_BLENDFACTOR_INV_DST_ALPHA       0x14
+#define PIPE_BLENDFACTOR_INV_DST_COLOR       0x15
+#define PIPE_BLENDFACTOR_INV_CONST_COLOR     0x17
+#define PIPE_BLENDFACTOR_INV_CONST_ALPHA     0x18
+#define PIPE_BLENDFACTOR_INV_SRC1_COLOR      0x19
+#define PIPE_BLENDFACTOR_INV_SRC1_ALPHA      0x1A
+
+#define PIPE_BLEND_ADD               0
+#define PIPE_BLEND_SUBTRACT          1
+#define PIPE_BLEND_REVERSE_SUBTRACT  2
+#define PIPE_BLEND_MIN               3
+#define PIPE_BLEND_MAX               4
+
+#define PIPE_LOGICOP_CLEAR            0
+#define PIPE_LOGICOP_NOR              1
+#define PIPE_LOGICOP_AND_INVERTED     2
+#define PIPE_LOGICOP_COPY_INVERTED    3
+#define PIPE_LOGICOP_AND_REVERSE      4
+#define PIPE_LOGICOP_INVERT           5
+#define PIPE_LOGICOP_XOR              6
+#define PIPE_LOGICOP_NAND             7
+#define PIPE_LOGICOP_AND              8
+#define PIPE_LOGICOP_EQUIV            9
+#define PIPE_LOGICOP_NOOP             10
+#define PIPE_LOGICOP_OR_INVERTED      11
+#define PIPE_LOGICOP_COPY             12
+#define PIPE_LOGICOP_OR_REVERSE       13
+#define PIPE_LOGICOP_OR               14
+#define PIPE_LOGICOP_SET              15  
+
+#define PIPE_MASK_R  0x1
+#define PIPE_MASK_G  0x2
+#define PIPE_MASK_B  0x4
+#define PIPE_MASK_A  0x8
+
+/**
+ * Inequality functions.  Used for depth test, stencil compare, alpha
+ * test, shadow compare, etc.
+ */
+#define PIPE_FUNC_NEVER    0
+#define PIPE_FUNC_LESS     1
+#define PIPE_FUNC_EQUAL    2
+#define PIPE_FUNC_LEQUAL   3
+#define PIPE_FUNC_GREATER  4
+#define PIPE_FUNC_NOTEQUAL 5
+#define PIPE_FUNC_GEQUAL   6
+#define PIPE_FUNC_ALWAYS   7
+
+/** Polygon fill mode */
+#define PIPE_POLYGON_MODE_FILL  0
+#define PIPE_POLYGON_MODE_LINE  1
+#define PIPE_POLYGON_MODE_POINT 2
+
+/** Polygon front/back window, also for culling */
+#define PIPE_WINDING_NONE 0
+#define PIPE_WINDING_CW   1
+#define PIPE_WINDING_CCW  2
+#define PIPE_WINDING_BOTH (PIPE_WINDING_CW | PIPE_WINDING_CCW)
+
+/** Stencil ops */
+#define PIPE_STENCIL_OP_KEEP       0
+#define PIPE_STENCIL_OP_ZERO       1
+#define PIPE_STENCIL_OP_REPLACE    2
+#define PIPE_STENCIL_OP_INCR       3
+#define PIPE_STENCIL_OP_DECR       4
+#define PIPE_STENCIL_OP_INCR_WRAP  5
+#define PIPE_STENCIL_OP_DECR_WRAP  6
+#define PIPE_STENCIL_OP_INVERT     7
+
+#define PIPE_TEX_WRAP_REPEAT                   0
+#define PIPE_TEX_WRAP_CLAMP                    1
+#define PIPE_TEX_WRAP_CLAMP_TO_EDGE            2
+#define PIPE_TEX_WRAP_CLAMP_TO_BORDER          3
+#define PIPE_TEX_WRAP_MIRROR_REPEAT            4
+#define PIPE_TEX_WRAP_MIRROR_CLAMP             5
+#define PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE     6
+#define PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER   7
+
+#define PIPE_TEX_FILTER_NEAREST                0
+#define PIPE_TEX_FILTER_LINEAR                 1
+#define PIPE_TEX_FILTER_NEAREST_MIPMAP_NEAREST 2
+#define PIPE_TEX_FILTER_NEAREST_MIPMAP_LINEAR  3
+#define PIPE_TEX_FILTER_LINEAR_MIPMAP_NEAREST  4
+#define PIPE_TEX_FILTER_LINEAR_MIPMAP_LINEAR   5
+
+#define PIPE_TEX_COMPARE_NONE          0
+#define PIPE_TEX_COMPARE_R_TO_TEXTURE  1
+
+/**
+ * Texture/surface image formats (preliminary)
+ */
+#define PIPE_FORMAT_NONE            0  /**< unstructured */
+#define PIPE_FORMAT_U_R8_G8_B8_A8   1  /**< ubyte[4] RGBA */
+#define PIPE_FORMAT_U_A8_R8_G8_B8   2  /**< ubyte[4] ARGB */
+#define PIPE_FORMAT_U_R5_G6_B5      3  /**< 5/6/5 RGB */
+#define PIPE_FORMAT_U_L8            4  /**< ubyte luminance */
+#define PIPE_FORMAT_U_A8            5  /**< ubyte alpha */
+#define PIPE_FORMAT_U_I8            6  /**< ubyte intensity */
+#define PIPE_FORMAT_U_L8_A8         7  /**< ubyte luminance, alpha */
+#define PIPE_FORMAT_YCBCR           8
+#define PIPE_FORMAT_YCBCR_REV       9
+#define PIPE_FORMAT_U_Z16          10  /**< ushort Z/depth */
+#define PIPE_FORMAT_U_Z32          11  /**< uint Z/depth */
+#define PIPE_FORMAT_F_Z32          12  /**< float Z/depth */
+#define PIPE_FORMAT_Z24_S8         13  /**< 24-bit Z + 8-bit stencil */
+#define PIPE_FORMAT_U_S8           14  /**< 8-bit stencil */
+
+
+/**
+ * Texture typess
+ */
+#define PIPE_TEXTURE_1D   0
+#define PIPE_TEXTURE_2D   1
+#define PIPE_TEXTURE_3D   2
+#define PIPE_TEXTURE_CUBE 3
+
+/**
+ * Buffer mapping access modes
+ */
+#define PIPE_MAP_READ         1
+#define PIPE_MAP_WRITE        2
+#define PIPE_MAP_READ_WRITE   3
+
+#endif
diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h
new file mode 100644 (file)
index 0000000..9973a7b
--- /dev/null
@@ -0,0 +1,303 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+
+/**
+ * Abstract graphics pipe state objects.
+ *
+ * Basic notes:
+ *   1. Want compact representations, so we use bitfields.
+ *   2. Put bitfields before other (GLfloat) fields.
+ */
+
+
+#ifndef PIPE_STATE_H
+#define PIPE_STATE_H
+
+#include "mtypes.h"
+
+
+
+/**
+ * Implementation limits
+ */
+#define PIPE_MAX_SAMPLERS     8
+#define PIPE_MAX_CLIP_PLANES  6
+#define PIPE_MAX_CONSTANT    32
+#define PIPE_ATTRIB_MAX      32
+#define PIPE_MAX_COLOR_BUFS   8
+
+
+/* fwd decl */
+struct pipe_surface;
+
+
+/***
+ *** State objects
+ ***/
+
+
+/**
+ * Primitive (point/line/tri) setup info
+ */
+struct pipe_setup_state
+{
+   GLuint flatshade:1;
+   GLuint light_twoside:1;
+
+   GLuint front_winding:2;  /**< PIPE_WINDING_x */
+
+   GLuint cull_mode:2;      /**< PIPE_WINDING_x */
+
+   GLuint fill_cw:2;        /**< PIPE_POLYGON_MODE_x */
+   GLuint fill_ccw:2;       /**< PIPE_POLYGON_MODE_x */
+
+   GLuint offset_cw:1;
+   GLuint offset_ccw:1;
+
+   GLuint scissor:1;
+
+   GLuint poly_smooth:1;
+   GLuint poly_stipple_enable:1;
+
+   GLuint line_smooth:1;
+   GLuint line_stipple_enable:1;
+
+   GLuint point_smooth:1;
+
+   GLuint multisample:1;         /* XXX maybe more ms state in future */
+
+   GLubyte line_stipple_factor;  /**< [1..256] actually */
+   GLushort line_stipple_pattern;
+   GLfloat line_width;
+   GLfloat point_size;           /**< used when no per-vertex size */
+   GLfloat offset_units;
+   GLfloat offset_scale;
+};
+
+struct pipe_poly_stipple {
+   GLuint stipple[32];
+};
+
+
+struct pipe_viewport_state {
+   GLfloat scale[4];
+   GLfloat translate[4];
+};
+
+struct pipe_scissor_state {
+   GLshort minx;
+   GLshort miny;
+   GLshort maxx;
+   GLshort maxy;
+};
+
+struct pipe_clip_state {
+   GLfloat ucp[PIPE_MAX_CLIP_PLANES][4];
+   GLuint nr;
+};
+
+
+struct pipe_constant_buffer {
+   GLfloat constant[PIPE_MAX_CONSTANT][4];
+   GLuint nr_constants;
+};
+
+
+struct pipe_fs_state {
+   GLbitfield inputs_read;             /* FRAG_ATTRIB_* */
+   const struct tgsi_token *tokens;
+   struct pipe_constant_buffer *constants; /* XXX temporary? */
+};
+
+struct pipe_depth_state
+{
+   GLuint enabled:1;   /**< depth test enabled? */
+   GLuint writemask:1; /**< allow depth buffer writes? */
+   GLuint func:3;      /**< depth test func (PIPE_FUNC_x) */
+   GLuint occlusion_count:1; /**< XXX move this elsewhere? */
+   GLfloat clear;      /**< Clear value in [0,1] (XXX correct place?) */
+};
+
+struct pipe_alpha_test_state {
+   GLuint enabled:1;
+   GLuint func:3;    /**< PIPE_FUNC_x */
+   GLfloat ref;      /**< reference value */
+};
+
+struct pipe_blend_state {
+   GLuint blend_enable:1;
+
+   GLuint rgb_func:3;          /**< PIPE_BLEND_x */
+   GLuint rgb_src_factor:5;    /**< PIPE_BLENDFACTOR_x */
+   GLuint rgb_dst_factor:5;    /**< PIPE_BLENDFACTOR_x */
+
+   GLuint alpha_func:3;        /**< PIPE_BLEND_x */
+   GLuint alpha_src_factor:5;  /**< PIPE_BLENDFACTOR_x */
+   GLuint alpha_dst_factor:5;  /**< PIPE_BLENDFACTOR_x */
+
+   GLuint logicop_enable:1;
+   GLuint logicop_func:4;      /**< PIPE_LOGICOP_x */
+
+   GLuint colormask:4;         /**< bitmask of PIPE_MASK_R/G/B/A */
+   GLuint dither:1;
+};
+
+struct pipe_blend_color {
+   GLfloat color[4];
+};
+
+struct pipe_clear_color_state
+{
+   GLfloat color[4];
+};
+
+struct pipe_stencil_state {
+   GLuint front_enabled:1;
+   GLuint front_func:3;     /**< PIPE_FUNC_x */
+   GLuint front_fail_op:3;  /**< PIPE_STENCIL_OP_x */
+   GLuint front_zpass_op:3; /**< PIPE_STENCIL_OP_x */
+   GLuint front_zfail_op:3; /**< PIPE_STENCIL_OP_x */
+   GLuint back_enabled:1;
+   GLuint back_func:3;      /**< PIPE_FUNC_x */
+   GLuint back_fail_op:3;   /**< PIPE_STENCIL_OP_x */
+   GLuint back_zpass_op:3;  /**< PIPE_STENCIL_OP_x */
+   GLuint back_zfail_op:3;  /**< PIPE_STENCIL_OP_x */
+   GLubyte ref_value[2];    /**< [0] = front, [1] = back */
+   GLubyte value_mask[2];
+   GLubyte write_mask[2];
+   GLubyte clear_value;
+};
+
+
+struct pipe_framebuffer_state
+{
+   /** multiple colorbuffers for multiple render targets */
+   GLuint num_cbufs;
+   struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS];
+
+   struct pipe_surface *zbuf;      /**< Z buffer */
+   struct pipe_surface *sbuf;      /**< Stencil buffer */
+   struct pipe_surface *abuf;      /**< Accum buffer */
+};
+
+
+/**
+ * Texture sampler state.
+ */
+struct pipe_sampler_state
+{
+   GLuint wrap_s:3;        /**< PIPE_TEX_WRAP_x */
+   GLuint wrap_t:3;        /**< PIPE_TEX_WRAP_x */
+   GLuint wrap_r:3;        /**< PIPE_TEX_WRAP_x */
+   GLuint min_filter:3;    /**< PIPE_TEX_FILTER_x */
+   GLuint mag_filter:1;    /**< PIPE_TEX_FILTER_LINEAR or _NEAREST */
+   GLuint compare:1;       /**< shadow/depth compare enabled? */
+   GLenum compare_mode:1;  /**< PIPE_TEX_COMPARE_x */
+   GLenum compare_func:3;  /**< PIPE_FUNC_x */
+   GLfloat shadow_ambient; /**< shadow test fail color/intensity */
+   GLfloat min_lod;
+   GLfloat max_lod;
+   GLfloat lod_bias;
+#if 0 /* need these? */
+   GLint BaseLevel;     /**< min mipmap level, OpenGL 1.2 */
+   GLint MaxLevel;      /**< max mipmap level, OpenGL 1.2 */
+   GLfloat border_color[4];
+#endif
+   GLfloat max_anisotropy;
+};
+
+
+/***
+ *** Non-state Objects
+ ***/
+
+
+/**
+ * A mappable buffer (vertex data, pixel data, etc)
+ * XXX replace with "intel_region".
+ */
+struct pipe_buffer
+{
+   void (*buffer_data)(struct pipe_buffer *pb, GLuint size, const void *src);
+   void (*buffer_sub_data)(struct pipe_buffer *pb, GLuint offset, GLuint size,
+                           const void *src);
+   void *(*map)(struct pipe_buffer *pb, GLuint access_mode);
+   void (*unmap)(struct pipe_buffer *pb);
+   GLubyte *ptr;     /**< address, only valid while mapped */
+   GLuint mode;      /**< PIPE_MAP_x, only valid while mapped */
+};
+
+
+/**
+ * 2D surface.
+ * May be a renderbuffer, texture mipmap level, etc.
+ */
+struct pipe_surface
+{
+   struct pipe_buffer buffer;  /**< surfaces can be mapped */
+   GLuint format:5;            /**< PIPE_FORMAT_x */
+   GLuint width, height;
+
+   GLint stride, cpp;
+   GLubyte *ptr;    /**< only valid while mapped, may not equal buffer->ptr */
+
+   void *rb;  /**< Ptr back to renderbuffer (temporary?) */
+
+   void (*resize)(struct pipe_surface *ps, GLuint width, GLuint height);
+};
+
+
+/**
+ * Texture object.
+ * Mipmap levels, cube faces, 3D slices can be accessed as surfaces.
+ */
+struct pipe_texture_object
+{
+   GLuint type:2;      /**< PIPE_TEXTURE_x */
+   GLuint format:5;    /**< PIPE_FORMAT_x */
+   GLuint width:13;    /**< 13 bits = 8K max size */
+   GLuint height:13;
+   GLuint depth:13;
+   GLuint mipmapped:1;
+
+   /** to access a 1D or 2D texture object as a surface */
+   struct pipe_surface *(*get_2d_surface)(struct pipe_texture_object *pto,
+                                          GLuint level);
+   /** to access a 3D texture object as a surface */
+   struct pipe_surface *(*get_3d_surface)(struct pipe_texture_object *pto,
+                                          GLuint level, GLuint slice);
+   /** to access a cube texture object as a surface */
+   struct pipe_surface *(*get_cube_surface)(struct pipe_texture_object *pto,
+                                            GLuint face, GLuint level);
+   /** when finished with surface: */
+   void (*release_surface)(struct pipe_texture_object *pto,
+                           struct pipe_surface *ps);
+};
+
+
+#endif
diff --git a/src/mesa/pipe/softpipe/Makefile b/src/mesa/pipe/softpipe/Makefile
new file mode 100644 (file)
index 0000000..12a8bd0
--- /dev/null
@@ -0,0 +1,3 @@
+default:
+       cd ../.. ; make
+
diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c
new file mode 100644 (file)
index 0000000..e83bc05
--- /dev/null
@@ -0,0 +1,71 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/* Author:
+ *    Brian Paul
+ */
+
+
+#include "sp_clear.h"
+#include "sp_context.h"
+#include "sp_surface.h"
+#include "colormac.h"
+
+
+void
+softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
+               GLboolean stencil, GLboolean accum)
+{
+   const struct softpipe_context *softpipe = softpipe_context(pipe);
+   const GLint x = softpipe->scissor.minx;
+   const GLint y = softpipe->scissor.miny;
+   const GLint w = softpipe->scissor.maxx - x;
+   const GLint h = softpipe->scissor.maxy - y;
+
+   if (color) {
+      GLuint i;
+      GLubyte clr[4];
+
+      UNCLAMPED_FLOAT_TO_UBYTE(clr[0], softpipe->clear_color.color[0]);
+      UNCLAMPED_FLOAT_TO_UBYTE(clr[1], softpipe->clear_color.color[1]);
+      UNCLAMPED_FLOAT_TO_UBYTE(clr[2], softpipe->clear_color.color[2]);
+      UNCLAMPED_FLOAT_TO_UBYTE(clr[3], softpipe->clear_color.color[3]);
+
+      for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
+         struct pipe_surface *ps = softpipe->framebuffer.cbufs[i];
+         struct softpipe_surface *sps = softpipe_surface(ps);
+         GLint j;
+         for (j = 0; j < h; j++) {
+            sps->write_mono_row_ub(sps, w, x, y + j, clr);
+         }
+      }
+   }
+
+   if (depth) {
+   }
+
+}
diff --git a/src/mesa/pipe/softpipe/sp_clear.h b/src/mesa/pipe/softpipe/sp_clear.h
new file mode 100644 (file)
index 0000000..f9db99d
--- /dev/null
@@ -0,0 +1,43 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/* Author:
+ *    Brian Paul
+ */
+
+#ifndef SP_CLEAR_H
+#define SP_CLEAR_H
+
+#include "pipe/p_state.h"
+struct pipe_context;
+
+extern void
+softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
+               GLboolean stencil, GLboolean accum);
+
+
+#endif /* SP_CLEAR_H */
diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c
new file mode 100644 (file)
index 0000000..8655aa8
--- /dev/null
@@ -0,0 +1,170 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/* Author:
+ *    Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "main/imports.h"
+#include "main/macros.h"
+#include "pipe/draw/draw_context.h"
+#include "pipe/p_defines.h"
+#include "sp_context.h"
+#include "sp_clear.h"
+#include "sp_state.h"
+#include "sp_surface.h"
+#include "sp_prim_setup.h"
+
+
+static void map_surfaces(struct softpipe_context *sp)
+{
+   GLuint i;
+
+   for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
+      struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.cbufs[i]);
+      struct pipe_buffer *buf = &sps->surface.buffer;
+      buf->map(buf, PIPE_MAP_READ_WRITE);
+   }
+
+   if (sp->framebuffer.zbuf) {
+      struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.zbuf);
+      struct pipe_buffer *buf = &sps->surface.buffer;
+      buf->map(buf, PIPE_MAP_READ_WRITE);
+   }
+
+   /* XXX depth & stencil bufs */
+}
+
+
+static void unmap_surfaces(struct softpipe_context *sp)
+{
+   GLuint i;
+
+   for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
+      struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.cbufs[i]);
+      struct pipe_buffer *buf = &sps->surface.buffer;
+      buf->unmap(buf);
+   }
+
+   if (sp->framebuffer.zbuf) {
+      struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.zbuf);
+      struct pipe_buffer *buf = &sps->surface.buffer;
+      buf->unmap(buf);
+   }
+   /* XXX depth & stencil bufs */
+}
+
+
+static void softpipe_destroy( struct pipe_context *pipe )
+{
+   struct softpipe_context *softpipe = softpipe_context( pipe );
+
+   draw_destroy( softpipe->draw );
+
+   free( softpipe );
+}
+
+
+static void softpipe_draw_vb( struct pipe_context *pipe,
+                            struct vertex_buffer *VB )
+{
+   struct softpipe_context *softpipe = softpipe_context( pipe );
+
+   if (softpipe->dirty)
+      softpipe_update_derived( softpipe );
+
+   /* XXX move mapping/unmapping to higher/coarser level? */
+   map_surfaces(softpipe);
+   draw_vb( softpipe->draw, VB );
+   unmap_surfaces(softpipe);
+}
+
+
+static void softpipe_reset_occlusion_counter(struct pipe_context *pipe)
+{
+   struct softpipe_context *softpipe = softpipe_context( pipe );
+   softpipe->occlusion_counter = 0;
+}
+
+/* XXX pipe param should be const */
+static GLuint softpipe_get_occlusion_counter(struct pipe_context *pipe)
+{
+   struct softpipe_context *softpipe = softpipe_context( pipe );
+   return softpipe->occlusion_counter;
+}
+
+
+struct pipe_context *softpipe_create( void )
+{
+   struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
+
+   softpipe->pipe.destroy = softpipe_destroy;
+   softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state;
+   softpipe->pipe.set_blend_color = softpipe_set_blend_color;
+   softpipe->pipe.set_blend_state = softpipe_set_blend_state;
+   softpipe->pipe.set_clip_state = softpipe_set_clip_state;
+   softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state;
+   softpipe->pipe.set_depth_state = softpipe_set_depth_test_state;
+   softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
+   softpipe->pipe.set_fs_state = softpipe_set_fs_state;
+   softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
+   softpipe->pipe.set_sampler_state = softpipe_set_sampler_state;
+   softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
+   softpipe->pipe.set_setup_state = softpipe_set_setup_state;
+   softpipe->pipe.set_stencil_state = softpipe_set_stencil_state;
+   softpipe->pipe.set_texture_state = softpipe_set_texture_state;
+   softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
+   softpipe->pipe.draw_vb = softpipe_draw_vb;
+   softpipe->pipe.clear = softpipe_clear;
+   softpipe->pipe.reset_occlusion_counter = softpipe_reset_occlusion_counter;
+   softpipe->pipe.get_occlusion_counter = softpipe_get_occlusion_counter;
+
+   softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
+   softpipe->quad.shade = sp_quad_shade_stage(softpipe);
+   softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
+   softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
+   softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe);
+   softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);
+   softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);
+   softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe);
+   softpipe->quad.blend = sp_quad_blend_stage(softpipe);
+   softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
+   softpipe->quad.output = sp_quad_output_stage(softpipe);
+
+   /*
+    * Create drawing context and plug our rendering stage into it.
+    */
+   softpipe->draw = draw_create();
+   draw_set_setup_stage(softpipe->draw, sp_draw_render_stage(softpipe));
+
+   /*
+    * XXX we could plug GL selection/feedback into the drawing pipeline
+    * by specifying a different setup/render stage.
+    */
+
+   return &softpipe->pipe;
+}
diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h
new file mode 100644 (file)
index 0000000..3c379c9
--- /dev/null
@@ -0,0 +1,160 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef SP_CONTEXT_H
+#define SP_CONTEXT_H
+
+#include "glheader.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+
+#include "sp_quad.h"
+
+
+struct softpipe_surface;
+struct draw_context;
+struct draw_stage;
+
+
+enum interp_mode {
+   INTERP_CONSTANT, 
+   INTERP_LINEAR, 
+   INTERP_PERSPECTIVE
+};
+
+
+#define SP_NEW_VIEWPORT      0x1
+#define SP_NEW_SETUP         0x2
+#define SP_NEW_FS            0x4
+#define SP_NEW_BLEND         0x8
+#define SP_NEW_CLIP         0x10
+#define SP_NEW_SCISSOR      0x20
+#define SP_NEW_STIPPLE      0x40
+#define SP_NEW_FRAMEBUFFER  0x80
+#define SP_NEW_ALPHA_TEST  0x100
+#define SP_NEW_DEPTH_TEST  0x200
+#define SP_NEW_SAMPLER     0x400
+#define SP_NEW_TEXTURE     0x800
+#define SP_NEW_STENCIL    0x1000
+
+
+struct softpipe_context {     
+   struct pipe_context pipe;  /**< base class */
+
+   /* The most recent drawing state as set by the driver:
+    */
+   struct pipe_alpha_test_state alpha_test;
+   struct pipe_blend_state blend;
+   struct pipe_blend_color blend_color;
+   struct pipe_clear_color_state clear_color;
+   struct pipe_clip_state clip;
+   struct pipe_depth_state depth_test;
+   struct pipe_framebuffer_state framebuffer;
+   struct pipe_fs_state fs;
+   struct pipe_poly_stipple poly_stipple;
+   struct pipe_scissor_state scissor;
+   struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
+   struct pipe_setup_state setup;
+   struct pipe_stencil_state stencil;
+   struct pipe_texture_object *texture[PIPE_MAX_SAMPLERS];
+   struct pipe_viewport_state viewport;
+   GLuint dirty;
+
+   /* Setup derived state.  TODO: this should be passed in the program
+    * tokens as parameters to DECL instructions.
+    * 
+    * For now we just set colors to CONST on flatshade, textures to
+    * perspective always and everything else to linear.
+    */
+   enum interp_mode interp[PIPE_ATTRIB_MAX];
+
+
+   /* FS + setup derived state:
+    */
+
+   /** Map fragment program attribute to quad/coef array slot */
+   GLuint fp_attr_to_slot[PIPE_ATTRIB_MAX];
+   /** Map vertex format attribute to a vertex attribute slot */
+   GLuint vf_attr_to_slot[PIPE_ATTRIB_MAX];
+   GLuint nr_attrs;
+   GLuint nr_frag_attrs;  /**< number of active fragment attribs */
+   GLbitfield attr_mask;  /**< bitfield of VF_ATTRIB_ indexes/bits */
+
+   GLboolean need_z;  /**< produce quad/fragment Z values? */
+   GLboolean need_w;  /**< produce quad/fragment W values? */
+
+#if 0
+   /* Stipple derived state:
+    */
+   GLubyte stipple_masks[16][16];
+#endif
+
+   /** Derived from scissor and surface bounds: */
+   struct pipe_scissor_state cliprect;
+
+   GLuint occlusion_counter;
+
+   GLuint line_stipple_counter;
+
+   /** Software quad rendering pipeline */
+   struct {
+      struct quad_stage *polygon_stipple;
+      struct quad_stage *shade;
+      struct quad_stage *alpha_test;
+      struct quad_stage *stencil_test;
+      struct quad_stage *depth_test;
+      struct quad_stage *occlusion;
+      struct quad_stage *coverage;
+      struct quad_stage *bufloop;
+      struct quad_stage *blend;
+      struct quad_stage *colormask;
+      struct quad_stage *output;
+
+      struct quad_stage *first; /**< points to one of the above stages */
+   } quad;
+
+   /** The primitive drawing context */
+   struct draw_context *draw;
+
+   struct pipe_surface *cbuf;      /**< current color buffer (one of cbufs) */
+};
+
+
+
+
+static INLINE struct softpipe_context *
+softpipe_context( struct pipe_context *pipe )
+{
+   return (struct softpipe_context *)pipe;
+}
+
+
+#endif /* SP_CONTEXT_H */
diff --git a/src/mesa/pipe/softpipe/sp_headers.h b/src/mesa/pipe/softpipe/sp_headers.h
new file mode 100644 (file)
index 0000000..68a8462
--- /dev/null
@@ -0,0 +1,95 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef SP_HEADERS_H
+#define SP_HEADERS_H
+
+
+#define PRIM_POINT 1
+#define PRIM_LINE  2
+#define PRIM_TRI   3
+
+
+/* The rasterizer generates 2x2 quads of fragment and feeds them to
+ * the current fp_machine (see below).  
+ */
+#define QUAD_BOTTOM_LEFT  0
+#define QUAD_BOTTOM_RIGHT 1
+#define QUAD_TOP_LEFT     2
+#define QUAD_TOP_RIGHT    3
+#define QUAD_SIZE        (2*2)
+
+#define MASK_BOTTOM_LEFT  0x1
+#define MASK_BOTTOM_RIGHT 0x2
+#define MASK_TOP_LEFT     0x4
+#define MASK_TOP_RIGHT    0x8
+#define MASK_ALL          0xf
+
+
+#define NUM_CHANNELS   4       /* avoid confusion between 4 pixels and 4 channels */
+
+
+struct setup_coefficient {
+   GLfloat a0[NUM_CHANNELS];   /* in an xyzw layout */
+   GLfloat dadx[NUM_CHANNELS];
+   GLfloat dady[NUM_CHANNELS];
+};
+
+
+
+/**
+ * Encodes everything we need to know about a 2x2 pixel block.  Uses
+ * "Channel-Serial" or "SoA" layout.  
+ */
+struct quad_header {
+   GLint x0;
+   GLint y0;
+   GLuint mask:4;
+   GLuint facing:1;   /**< Front (0) or back (1) facing? */
+   GLuint prim:2;     /**< PRIM_POINT, LINE, TRI */
+
+   struct {
+      GLfloat color[4][QUAD_SIZE];     /* rrrr, gggg, bbbb, aaaa */
+      GLfloat depth[QUAD_SIZE];
+   } outputs;
+
+   GLfloat coverage[QUAD_SIZE];    /** fragment coverage for antialiasing */
+
+   const struct setup_coefficient *coef;
+
+   const enum interp_mode *interp; /* XXX: this information should be
+                                   * encoded in fragment program DECL
+                                   * statements. */
+
+   GLuint nr_attrs;
+};
+
+
+#endif /* SP_HEADERS_H */
diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c
new file mode 100644 (file)
index 0000000..4e66f40
--- /dev/null
@@ -0,0 +1,1047 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  Primitive rasterization/rendering (points, lines, triangles)
+ *
+ * \author  Keith Whitwell <keith@tungstengraphics.com>
+ * \author  Brian Paul
+ */
+
+
+#include "imports.h"
+#include "macros.h"
+
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "pipe/draw/draw_private.h"
+#include "sp_quad.h"
+#include "sp_prim_setup.h"
+
+
+/**
+ * Triangle edge info
+ */
+struct edge {
+   GLfloat dx;                 /**< X(v1) - X(v0), used only during setup */
+   GLfloat dy;                 /**< Y(v1) - Y(v0), used only during setup */
+   GLfloat dxdy;               /**< dx/dy */
+   GLfloat sx, sy;             /**< first sample point coord */
+   GLint lines;                        /**< number of lines on this edge */
+};
+
+
+/**
+ * Triangle setup info (derived from draw_stage).
+ * Also used for line drawing (taking some liberties).
+ */
+struct setup_stage {
+   struct draw_stage stage; /**< This must be first (base class) */
+
+   struct softpipe_context *softpipe;
+
+   /* Vertices are just an array of floats making up each attribute in
+    * turn.  Currently fixed at 4 floats, but should change in time.
+    * Codegen will help cope with this.
+    */
+   const struct vertex_header *vmax;
+   const struct vertex_header *vmid;
+   const struct vertex_header *vmin;
+   const struct vertex_header *vprovoke;
+
+   struct edge ebot;
+   struct edge etop;
+   struct edge emaj;
+
+   GLfloat oneoverarea;
+
+   struct setup_coefficient coef[FRAG_ATTRIB_MAX];
+   struct quad_header quad; 
+
+   struct {
+      GLint left[2];   /**< [0] = row0, [1] = row1 */
+      GLint right[2];
+      GLint y;
+      GLuint y_flags;
+      GLuint mask;     /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */
+   } span;
+};
+
+
+
+/**
+ * Basically a cast wrapper.
+ */
+static INLINE struct setup_stage *setup_stage( struct draw_stage *stage )
+{
+   return (struct setup_stage *)stage;
+}
+
+
+/**
+ * Clip setup->quad against the scissor/surface bounds.
+ */
+static INLINE void
+quad_clip(struct setup_stage *setup)
+{
+   const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect;
+   if (setup->quad.x0 >= cliprect->maxx ||
+       setup->quad.y0 >= cliprect->maxy ||
+       setup->quad.x0 + 1 < cliprect->minx ||
+       setup->quad.y0 + 1 < cliprect->miny) {
+      /* totally clipped */
+      setup->quad.mask = 0x0;
+      return;
+   }
+   if (setup->quad.x0 < cliprect->minx)
+      setup->quad.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT);
+   if (setup->quad.y0 < cliprect->miny)
+      setup->quad.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT);
+   if (setup->quad.x0 == cliprect->maxx - 1)
+      setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT);
+   if (setup->quad.y0 == cliprect->maxy - 1)
+      setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT);
+}
+
+
+/**
+ * Emit a quad (pass to next stage) with clipping.
+ */
+static INLINE void
+clip_emit_quad(struct setup_stage *setup)
+{
+   quad_clip(setup);
+   if (setup->quad.mask) {
+      struct softpipe_context *sp = setup->softpipe;
+      sp->quad.first->run(sp->quad.first, &setup->quad);
+   }
+}
+
+
+/**
+ * Emit a quad (pass to next stage).  No clipping is done.
+ */
+static INLINE void
+emit_quad( struct setup_stage *setup, GLint x, GLint y, GLuint mask )
+{
+   struct softpipe_context *sp = setup->softpipe;
+   setup->quad.x0 = x;
+   setup->quad.y0 = y;
+   setup->quad.mask = mask;
+   sp->quad.first->run(sp->quad.first, &setup->quad);
+}
+
+
+/**
+ * Given an X or Y coordinate, return the block/quad coordinate that it
+ * belongs to.
+ */
+static INLINE GLint block( GLint x )
+{
+   return x & ~1;
+}
+
+
+/**
+ * Compute mask which indicates which pixels in the 2x2 quad are actually inside
+ * the triangle's bounds.
+ *
+ * this is pretty nasty...  may need to rework flush_spans again to
+ * fix it, if possible.
+ */
+static GLuint calculate_mask( struct setup_stage *setup,
+                           GLint x )
+{
+   GLuint mask = 0;
+
+   if (x >= setup->span.left[0] && x < setup->span.right[0]) 
+      mask |= MASK_BOTTOM_LEFT;
+
+   if (x >= setup->span.left[1] && x < setup->span.right[1]) 
+      mask |= MASK_TOP_LEFT;
+      
+   if (x+1 >= setup->span.left[0] && x+1 < setup->span.right[0]) 
+      mask |= MASK_BOTTOM_RIGHT;
+
+   if (x+1 >= setup->span.left[1] && x+1 < setup->span.right[1]) 
+      mask |= MASK_TOP_RIGHT;
+
+   return mask;
+}
+
+
+/**
+ * Render a horizontal span of quads
+ */
+static void flush_spans( struct setup_stage *setup )
+{
+   GLint minleft, maxright;
+   GLint x;
+
+   switch (setup->span.y_flags) {      
+   case 3:
+      minleft = MIN2(setup->span.left[0], setup->span.left[1]);
+      maxright = MAX2(setup->span.right[0], setup->span.right[1]);
+      break;
+
+   case 1:
+      minleft = setup->span.left[0];
+      maxright = setup->span.right[0];
+      break;
+
+   case 2:
+      minleft = setup->span.left[1];
+      maxright = setup->span.right[1];
+      break;
+
+   default:
+      return;
+   }
+
+
+   for (x = block(minleft); x <= block(maxright); )
+   {
+      emit_quad( setup, x, setup->span.y, 
+                 calculate_mask( setup, x ) );
+      x += 2;
+   }
+
+   setup->span.y = 0;
+   setup->span.y_flags = 0;
+   setup->span.right[0] = 0;
+   setup->span.right[1] = 0;
+}
+
+
+static GLboolean setup_sort_vertices( struct setup_stage *setup,
+                                     const struct prim_header *prim )
+{
+   const struct vertex_header *v0 = prim->v[0];
+   const struct vertex_header *v1 = prim->v[1];
+   const struct vertex_header *v2 = prim->v[2];
+
+   setup->vprovoke = v2;
+
+   /* determine bottom to top order of vertices */
+   {
+      GLfloat y0 = v0->data[0][1];
+      GLfloat y1 = v1->data[0][1];
+      GLfloat y2 = v2->data[0][1];
+      if (y0 <= y1) {
+        if (y1 <= y2) {
+           /* y0<=y1<=y2 */
+           setup->vmin = v0;   
+           setup->vmid = v1;   
+           setup->vmax = v2;
+        }
+        else if (y2 <= y0) {
+           /* y2<=y0<=y1 */
+           setup->vmin = v2;   
+           setup->vmid = v0;   
+           setup->vmax = v1;   
+        }
+        else {
+           /* y0<=y2<=y1 */
+           setup->vmin = v0;   
+           setup->vmid = v2;   
+           setup->vmax = v1;  
+        }
+      }
+      else {
+        if (y0 <= y2) {
+           /* y1<=y0<=y2 */
+           setup->vmin = v1;   
+           setup->vmid = v0;   
+           setup->vmax = v2;  
+        }
+        else if (y2 <= y1) {
+           /* y2<=y1<=y0 */
+           setup->vmin = v2;   
+           setup->vmid = v1;   
+           setup->vmax = v0;  
+        }
+        else {
+           /* y1<=y2<=y0 */
+           setup->vmin = v1;   
+           setup->vmid = v2;   
+           setup->vmax = v0;
+        }
+      }
+   }
+
+   setup->ebot.dx = setup->vmid->data[0][0] - setup->vmin->data[0][0];
+   setup->ebot.dy = setup->vmid->data[0][1] - setup->vmin->data[0][1];
+   setup->emaj.dx = setup->vmax->data[0][0] - setup->vmin->data[0][0];
+   setup->emaj.dy = setup->vmax->data[0][1] - setup->vmin->data[0][1];
+   setup->etop.dx = setup->vmax->data[0][0] - setup->vmid->data[0][0];
+   setup->etop.dy = setup->vmax->data[0][1] - setup->vmid->data[0][1];
+
+   /*
+    * Compute triangle's area.  Use 1/area to compute partial
+    * derivatives of attributes later.
+    *
+    * The area will be the same as prim->det, but the sign may be
+    * different depending on how the vertices get sorted above.
+    *
+    * To determine whether the primitive is front or back facing we
+    * use the prim->det value because its sign is correct.
+    */
+   {
+      const GLfloat area = (setup->emaj.dx * setup->ebot.dy - 
+                           setup->ebot.dx * setup->emaj.dy);
+
+      setup->oneoverarea = 1.0 / area;
+      /*
+      _mesa_printf("%s one-over-area %f  area %f  det %f\n",
+                   __FUNCTION__, setup->oneoverarea, area, prim->det );
+      */
+   }
+
+   /* We need to know if this is a front or back-facing triangle for:
+    *  - the GLSL gl_FrontFacing fragment attribute (bool)
+    *  - two-sided stencil test
+    */
+   setup->quad.facing = (prim->det > 0.0) ^ (setup->softpipe->setup.front_winding == PIPE_WINDING_CW);
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Compute a0 for a constant-valued coefficient (GL_FLAT shading).
+ * The value value comes from vertex->data[slot][i].
+ * The result will be put into setup->coef[slot].a0[i].
+ * \param slot  which attribute slot 
+ * \param i  which component of the slot (0..3)
+ */
+static void const_coeff( struct setup_stage *setup,
+                        GLuint slot,
+                        GLuint i )
+{
+   assert(slot < FRAG_ATTRIB_MAX);
+   assert(i <= 3);
+
+   setup->coef[slot].dadx[i] = 0;
+   setup->coef[slot].dady[i] = 0;
+
+   /* need provoking vertex info!
+    */
+   setup->coef[slot].a0[i] = setup->vprovoke->data[slot][i];
+}
+
+
+/**
+ * Compute a0, dadx and dady for a linearly interpolated coefficient,
+ * for a triangle.
+ */
+static void tri_linear_coeff( struct setup_stage *setup,
+                              GLuint slot,
+                              GLuint i)
+{
+   GLfloat botda = setup->vmid->data[slot][i] - setup->vmin->data[slot][i];
+   GLfloat majda = setup->vmax->data[slot][i] - setup->vmin->data[slot][i];
+   GLfloat a = setup->ebot.dy * majda - botda * setup->emaj.dy;
+   GLfloat b = setup->emaj.dx * botda - majda * setup->ebot.dx;
+   
+   assert(slot < FRAG_ATTRIB_MAX);
+   assert(i <= 3);
+
+   setup->coef[slot].dadx[i] = a * setup->oneoverarea;
+   setup->coef[slot].dady[i] = b * setup->oneoverarea;
+
+   /* calculate a0 as the value which would be sampled for the
+    * fragment at (0,0), taking into account that we want to sample at
+    * pixel centers, in other words (0.5, 0.5).
+    *
+    * this is neat but unfortunately not a good way to do things for
+    * triangles with very large values of dadx or dady as it will
+    * result in the subtraction and re-addition from a0 of a very
+    * large number, which means we'll end up loosing a lot of the
+    * fractional bits and precision from a0.  the way to fix this is
+    * to define a0 as the sample at a pixel center somewhere near vmin
+    * instead - i'll switch to this later.
+    */
+   setup->coef[slot].a0[i] = (setup->vmin->data[slot][i] - 
+                           (setup->coef[slot].dadx[i] * (setup->vmin->data[0][0] - 0.5) + 
+                            setup->coef[slot].dady[i] * (setup->vmin->data[0][1] - 0.5)));
+
+   /*
+   _mesa_printf("attr[%d].%c: %f dx:%f dy:%f\n",
+               slot, "xyzw"[i], 
+               setup->coef[slot].a0[i],
+               setup->coef[slot].dadx[i],
+               setup->coef[slot].dady[i]);
+   */
+}
+
+
+/**
+ * Compute a0, dadx and dady for a perspective-corrected interpolant,
+ * for a triangle.
+ */
+static void tri_persp_coeff( struct setup_stage *setup,
+                             GLuint slot,
+                             GLuint i )
+{
+   /* premultiply by 1/w:
+    */
+   GLfloat mina = setup->vmin->data[slot][i] * setup->vmin->data[0][3];
+   GLfloat mida = setup->vmid->data[slot][i] * setup->vmid->data[0][3];
+   GLfloat maxa = setup->vmax->data[slot][i] * setup->vmax->data[0][3];
+
+   GLfloat botda = mida - mina;
+   GLfloat majda = maxa - mina;
+   GLfloat a = setup->ebot.dy * majda - botda * setup->emaj.dy;
+   GLfloat b = setup->emaj.dx * botda - majda * setup->ebot.dx;
+      
+   assert(slot < FRAG_ATTRIB_MAX);
+   assert(i <= 3);
+
+   setup->coef[slot].dadx[i] = a * setup->oneoverarea;
+   setup->coef[slot].dady[i] = b * setup->oneoverarea;
+   setup->coef[slot].a0[i] = (mina - 
+                           (setup->coef[slot].dadx[i] * (setup->vmin->data[0][0] - 0.5) + 
+                            setup->coef[slot].dady[i] * (setup->vmin->data[0][1] - 0.5)));
+}
+
+
+
+/**
+ * Compute the setup->coef[] array dadx, dady, a0 values.
+ * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized.
+ */
+static void setup_tri_coefficients( struct setup_stage *setup )
+{
+   const enum interp_mode *interp = setup->softpipe->interp;
+   GLuint slot, j;
+
+   /* z and w are done by linear interpolation:
+    */
+   tri_linear_coeff(setup, 0, 2);
+   tri_linear_coeff(setup, 0, 3);
+
+   /* setup interpolation for all the remaining attributes:
+    */
+   for (slot = 1; slot < setup->quad.nr_attrs; slot++) {
+      switch (interp[slot]) {
+      case INTERP_CONSTANT:
+        for (j = 0; j < NUM_CHANNELS; j++)
+           const_coeff(setup, slot, j);
+        break;
+      
+      case INTERP_LINEAR:
+        for (j = 0; j < NUM_CHANNELS; j++)
+           tri_linear_coeff(setup, slot, j);
+        break;
+
+      case INTERP_PERSPECTIVE:
+        for (j = 0; j < NUM_CHANNELS; j++)
+           tri_persp_coeff(setup, slot, j);
+        break;
+      }
+   }
+}
+
+
+
+static void setup_tri_edges( struct setup_stage *setup )
+{
+   GLfloat vmin_x = setup->vmin->data[0][0] + 0.5;
+   GLfloat vmid_x = setup->vmid->data[0][0] + 0.5;
+
+   GLfloat vmin_y = setup->vmin->data[0][1] - 0.5;
+   GLfloat vmid_y = setup->vmid->data[0][1] - 0.5;
+   GLfloat vmax_y = setup->vmax->data[0][1] - 0.5;
+
+   setup->emaj.sy = ceilf(vmin_y);
+   setup->emaj.lines = (GLint) ceilf(vmax_y - setup->emaj.sy);
+   setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy;
+   setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy;
+
+   setup->etop.sy = ceilf(vmid_y);
+   setup->etop.lines = (GLint) ceilf(vmax_y - setup->etop.sy);
+   setup->etop.dxdy = setup->etop.dx / setup->etop.dy;
+   setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy;
+
+   setup->ebot.sy = ceilf(vmin_y);
+   setup->ebot.lines = (GLint) ceilf(vmid_y - setup->ebot.sy);
+   setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy;
+   setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy;
+}
+
+
+/**
+ * Render the upper or lower half of a triangle.
+ * Scissoring/cliprect is applied here too.
+ */
+static void subtriangle( struct setup_stage *setup,
+                        struct edge *eleft,
+                        struct edge *eright,
+                        GLuint lines )
+{
+   const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect;
+   GLint y, start_y, finish_y;
+   GLint sy = (GLint)eleft->sy;
+
+   assert((GLint)eleft->sy == (GLint) eright->sy);
+
+   /* clip top/bottom */
+   start_y = sy;
+   finish_y = sy + lines;
+
+   if (start_y < cliprect->miny)
+      start_y = cliprect->miny;
+
+   if (finish_y > cliprect->maxy)
+      finish_y = cliprect->maxy;
+
+   start_y -= sy;
+   finish_y -= sy;
+
+   /*
+   _mesa_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y);  
+   */
+
+   for (y = start_y; y < finish_y; y++) {
+
+      /* avoid accumulating adds as floats don't have the precision to
+       * accurately iterate large triangle edges that way.  luckily we
+       * can just multiply these days.
+       *
+       * this is all drowned out by the attribute interpolation anyway.
+       */
+      GLint left = (GLint)(eleft->sx + y * eleft->dxdy);
+      GLint right = (GLint)(eright->sx + y * eright->dxdy);
+
+      /* clip left/right */
+      if (left < cliprect->minx)
+         left = cliprect->minx;
+      if (right > cliprect->maxx)
+         right = cliprect->maxx;
+
+      if (left < right) {
+        GLint _y = sy+y;
+        if (block(_y) != setup->span.y) {
+           flush_spans(setup);
+           setup->span.y = block(_y);
+        }
+   
+        setup->span.left[_y&1] = left;
+        setup->span.right[_y&1] = right;
+        setup->span.y_flags |= 1<<(_y&1);
+      }
+   } 
+
+
+   /* save the values so that emaj can be restarted:
+    */
+   eleft->sx += lines * eleft->dxdy;
+   eright->sx += lines * eright->dxdy;
+   eleft->sy += lines;
+   eright->sy += lines;
+}
+
+
+/**
+ * Do setup for triangle rasterization, then render the triangle.
+ */
+static void setup_tri( struct draw_stage *stage,
+                      struct prim_header *prim )
+{
+   struct setup_stage *setup = setup_stage( stage );
+
+   /*
+   _mesa_printf("%s\n", __FUNCTION__ );
+   */
+
+   setup_sort_vertices( setup, prim );
+   setup_tri_coefficients( setup );
+   setup_tri_edges( setup );
+
+   setup->quad.prim = PRIM_TRI;
+
+   setup->span.y = 0;
+   setup->span.y_flags = 0;
+   setup->span.right[0] = 0;
+   setup->span.right[1] = 0;
+   /*   setup->span.z_mode = tri_z_mode( setup->ctx ); */
+
+   /*   init_constant_attribs( setup ); */
+      
+   if (setup->oneoverarea < 0.0) {
+      /* emaj on left:
+       */
+      subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines );
+      subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines );
+   }
+   else {
+      /* emaj on right:
+       */
+      subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines );
+      subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines );
+   }
+
+   flush_spans( setup );
+}
+
+
+
+/**
+ * Compute a0, dadx and dady for a linearly interpolated coefficient,
+ * for a line.
+ */
+static void
+line_linear_coeff(struct setup_stage *setup, GLuint slot, GLuint i)
+{
+   const GLfloat dz = setup->vmax->data[slot][i] - setup->vmin->data[slot][i];
+   const GLfloat dadx = dz * setup->emaj.dx * setup->oneoverarea;
+   const GLfloat dady = dz * setup->emaj.dy * setup->oneoverarea;
+   setup->coef[slot].dadx[i] = dadx;
+   setup->coef[slot].dady[i] = dady;
+   setup->coef[slot].a0[i]
+      = (setup->vmin->data[slot][i] - 
+         (dadx * (setup->vmin->data[0][0] - 0.5) + 
+          dady * (setup->vmin->data[0][1] - 0.5)));
+}
+
+
+/**
+ * Compute a0, dadx and dady for a perspective-corrected interpolant,
+ * for a line.
+ */
+static void
+line_persp_coeff(struct setup_stage *setup, GLuint slot, GLuint i)
+{
+   /* XXX to do */
+   line_linear_coeff(setup, slot, i); /* XXX temporary */
+}
+
+
+/**
+ * Compute the setup->coef[] array dadx, dady, a0 values.
+ * Must be called after setup->vmin,vmax are initialized.
+ */
+static INLINE void
+setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
+{
+   const enum interp_mode *interp = setup->softpipe->interp;
+   GLuint slot, j;
+
+   /* use setup->vmin, vmax to point to vertices */
+   setup->vprovoke = prim->v[1];
+   setup->vmin = prim->v[0];
+   setup->vmax = prim->v[1];
+
+   setup->emaj.dx = setup->vmax->data[0][0] - setup->vmin->data[0][0];
+   setup->emaj.dy = setup->vmax->data[0][1] - setup->vmin->data[0][1];
+   /* NOTE: this is not really 1/area */
+   setup->oneoverarea = 1.0 / (setup->emaj.dx * setup->emaj.dx +
+                               setup->emaj.dy * setup->emaj.dy);
+
+   /* z and w are done by linear interpolation:
+    */
+   line_linear_coeff(setup, 0, 2);
+   line_linear_coeff(setup, 0, 3);
+
+   /* setup interpolation for all the remaining attributes:
+    */
+   for (slot = 1; slot < setup->quad.nr_attrs; slot++) {
+      switch (interp[slot]) {
+      case INTERP_CONSTANT:
+        for (j = 0; j < NUM_CHANNELS; j++)
+           const_coeff(setup, slot, j);
+        break;
+      
+      case INTERP_LINEAR:
+        for (j = 0; j < NUM_CHANNELS; j++)
+           line_linear_coeff(setup, slot, j);
+        break;
+
+      case INTERP_PERSPECTIVE:
+        for (j = 0; j < NUM_CHANNELS; j++)
+           line_persp_coeff(setup, slot, j);
+        break;
+      }
+   }
+}
+
+
+/**
+ * Plot a pixel in a line segment.
+ */
+static INLINE void
+plot(struct setup_stage *setup, GLint x, GLint y)
+{
+   const GLint iy = y & 1;
+   const GLint ix = x & 1;
+   const GLint quadX = x - ix;
+   const GLint quadY = y - iy;
+   const GLint mask = (1 << ix) << (2 * iy);
+
+   if (quadX != setup->quad.x0 || 
+       quadY != setup->quad.y0) 
+   {
+      /* flush prev quad, start new quad */
+
+      if (setup->quad.x0 != -1)
+         clip_emit_quad(setup);
+
+      setup->quad.x0 = quadX;
+      setup->quad.y0 = quadY;
+      setup->quad.mask = 0x0;
+   }
+
+   setup->quad.mask |= mask;
+}
+
+
+/**
+ * Determine whether or not to emit a line fragment by checking
+ * line stipple pattern.
+ */
+static INLINE GLuint
+stipple_test(GLint counter, GLushort pattern, GLint factor)
+{
+   GLint b = (counter / factor) & 0xf;
+   return (1 << b) & pattern;
+}
+
+
+/**
+ * Do setup for line rasterization, then render the line.
+ * XXX single-pixel width, no stipple, etc
+ */
+static void
+setup_line(struct draw_stage *stage, struct prim_header *prim)
+{
+   const struct vertex_header *v0 = prim->v[0];
+   const struct vertex_header *v1 = prim->v[1];
+   struct setup_stage *setup = setup_stage( stage );
+   struct softpipe_context *sp = setup->softpipe;
+
+   GLint x0 = (GLint) v0->data[0][0];
+   GLint x1 = (GLint) v1->data[0][0];
+   GLint y0 = (GLint) v0->data[0][1];
+   GLint y1 = (GLint) v1->data[0][1];
+   GLint dx = x1 - x0;
+   GLint dy = y1 - y0;
+   GLint xstep, ystep;
+
+   if (dx == 0 && dy == 0)
+      return;
+
+   setup_line_coefficients(setup, prim);
+
+   if (dx < 0) {
+      dx = -dx;   /* make positive */
+      xstep = -1;
+   }
+   else {
+      xstep = 1;
+   }
+
+   if (dy < 0) {
+      dy = -dy;   /* make positive */
+      ystep = -1;
+   }
+   else {
+      ystep = 1;
+   }
+
+   assert(dx >= 0);
+   assert(dy >= 0);
+
+   setup->quad.x0 = setup->quad.y0 = -1;
+   setup->quad.mask = 0x0;
+   setup->quad.prim = PRIM_LINE;
+   /* XXX temporary: set coverage to 1.0 so the line appears
+    * if AA mode happens to be enabled.
+    */
+   setup->quad.coverage[0] =
+   setup->quad.coverage[1] =
+   setup->quad.coverage[2] =
+   setup->quad.coverage[3] = 1.0;
+
+   if (dx > dy) {
+      /*** X-major line ***/
+      GLint i;
+      const GLint errorInc = dy + dy;
+      GLint error = errorInc - dx;
+      const GLint errorDec = error - dx;
+
+      for (i = 0; i < dx; i++) {
+         if (!sp->setup.line_stipple_enable ||
+             stipple_test(sp->line_stipple_counter,
+                          sp->setup.line_stipple_pattern,
+                          sp->setup.line_stipple_factor + 1)) {
+             plot(setup, x0, y0);
+         }
+
+         x0 += xstep;
+         if (error < 0) {
+            error += errorInc;
+         }
+         else {
+            error += errorDec;
+            y0 += ystep;
+         }
+
+         sp->line_stipple_counter++;
+      }
+   }
+   else {
+      /*** Y-major line ***/
+      GLint i;
+      const GLint errorInc = dx + dx;
+      GLint error = errorInc - dy;
+      const GLint errorDec = error - dy;
+
+      for (i = 0; i < dy; i++) {
+         if (!sp->setup.line_stipple_enable ||
+             stipple_test(sp->line_stipple_counter,
+                          sp->setup.line_stipple_pattern,
+                          sp->setup.line_stipple_factor + 1)) {
+            plot(setup, x0, y0);
+         }
+
+         y0 += ystep;
+
+         if (error < 0) {
+            error += errorInc;
+         }
+         else {
+            error += errorDec;
+            x0 += xstep;
+         }
+
+         sp->line_stipple_counter++;
+      }
+   }
+
+   /* draw final quad */
+   if (setup->quad.mask) {
+      clip_emit_quad(setup);
+   }
+}
+
+
+/**
+ * Do setup for point rasterization, then render the point.
+ * Round or square points...
+ * XXX could optimize a lot for 1-pixel points.
+ */
+static void
+setup_point(struct draw_stage *stage, struct prim_header *prim)
+{
+   struct setup_stage *setup = setup_stage( stage );
+   /*XXX this should be a vertex attrib! */
+   const GLfloat halfSize = 0.5 * setup->softpipe->setup.point_size;
+   const GLboolean round = setup->softpipe->setup.point_smooth;
+   const struct vertex_header *v0 = prim->v[0];
+   const GLfloat x = v0->data[FRAG_ATTRIB_WPOS][0];
+   const GLfloat y = v0->data[FRAG_ATTRIB_WPOS][1];
+   GLuint slot, j;
+
+   /* For points, all interpolants are constant-valued.
+    * However, for point sprites, we'll need to setup texcoords appropriately.
+    * XXX: which coefficients are the texcoords???
+    * We may do point sprites as textured quads...
+    *
+    * KW: We don't know which coefficients are texcoords - ultimately
+    * the choice of what interpolation mode to use for each attribute
+    * should be determined by the fragment program, using
+    * per-attribute declaration statements that include interpolation
+    * mode as a parameter.  So either the fragment program will have
+    * to be adjusted for pointsprite vs normal point behaviour, or
+    * otherwise a special interpolation mode will have to be defined
+    * which matches the required behaviour for point sprites.  But -
+    * the latter is not a feature of normal hardware, and as such
+    * probably should be ruled out on that basis.
+    */
+   setup->vprovoke = prim->v[0];
+   const_coeff(setup, 0, 2);
+   const_coeff(setup, 0, 3);
+   for (slot = 1; slot < setup->quad.nr_attrs; slot++) {
+      for (j = 0; j < NUM_CHANNELS; j++)
+         const_coeff(setup, slot, j);
+   }
+
+   setup->quad.prim = PRIM_POINT;
+
+   if (halfSize <= 0.5 && !round) {
+      /* special case for 1-pixel points */
+      const GLint ix = ((GLint) x) & 1;
+      const GLint iy = ((GLint) y) & 1;
+      setup->quad.x0 = x - ix;
+      setup->quad.y0 = y - iy;
+      setup->quad.mask = (1 << ix) << (2 * iy);
+      clip_emit_quad(setup);
+   }
+   else {
+      const GLint ixmin = block((GLint) (x - halfSize));
+      const GLint ixmax = block((GLint) (x + halfSize));
+      const GLint iymin = block((GLint) (y - halfSize));
+      const GLint iymax = block((GLint) (y + halfSize));
+      GLint ix, iy;
+
+      if (round) {
+         /* rounded points */
+         const GLfloat rmin = halfSize - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
+         const GLfloat rmax = halfSize + 0.7071F;
+         const GLfloat rmin2 = MAX2(0.0F, rmin * rmin);
+         const GLfloat rmax2 = rmax * rmax;
+         const GLfloat cscale = 1.0F / (rmax2 - rmin2);
+
+         for (iy = iymin; iy <= iymax; iy += 2) {
+            for (ix = ixmin; ix <= ixmax; ix += 2) {
+               GLfloat dx, dy, dist2, cover;
+
+               setup->quad.mask = 0x0;
+
+               dx = (ix + 0.5) - x;
+               dy = (iy + 0.5) - y;
+               dist2 = dx * dx + dy * dy;
+               if (dist2 <= rmax2) {
+                  cover = 1.0F - (dist2 - rmin2) * cscale;
+                  setup->quad.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0);
+                  setup->quad.mask |= MASK_BOTTOM_LEFT;
+               }
+
+               dx = (ix + 1.5) - x;
+               dy = (iy + 0.5) - y;
+               dist2 = dx * dx + dy * dy;
+               if (dist2 <= rmax2) {
+                  cover = 1.0F - (dist2 - rmin2) * cscale;
+                  setup->quad.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0);
+                  setup->quad.mask |= MASK_BOTTOM_RIGHT;
+               }
+
+               dx = (ix + 0.5) - x;
+               dy = (iy + 1.5) - y;
+               dist2 = dx * dx + dy * dy;
+               if (dist2 <= rmax2) {
+                  cover = 1.0F - (dist2 - rmin2) * cscale;
+                  setup->quad.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0);
+                  setup->quad.mask |= MASK_TOP_LEFT;
+               }
+
+               dx = (ix + 1.5) - x;
+               dy = (iy + 1.5) - y;
+               dist2 = dx * dx + dy * dy;
+               if (dist2 <= rmax2) {
+                  cover = 1.0F - (dist2 - rmin2) * cscale;
+                  setup->quad.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0);
+                  setup->quad.mask |= MASK_TOP_RIGHT;
+               }
+
+               if (setup->quad.mask) {
+                  setup->quad.x0 = ix;
+                  setup->quad.y0 = iy;
+                  clip_emit_quad(setup);
+               }
+            }
+         }
+      }
+      else {
+         /* square points */
+         for (iy = iymin; iy <= iymax; iy += 2) {
+            for (ix = ixmin; ix <= ixmax; ix += 2) {
+               setup->quad.mask = 0xf;
+
+               if (ix + 0.5 < x - halfSize) {
+                  /* fragment is past left edge of point, turn off left bits */
+                  setup->quad.mask &= ~(MASK_BOTTOM_LEFT | MASK_TOP_LEFT);
+               }
+
+               if (ix + 1.5 > x + halfSize) {
+                  /* past the right edge */
+                  setup->quad.mask &= ~(MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT);
+               }
+
+               if (iy + 0.5 < y - halfSize) {
+                  /* below the bottom edge */
+                  setup->quad.mask &= ~(MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT);
+               }
+
+               if (iy + 1.5 > y + halfSize) {
+                  /* above the top edge */
+                  setup->quad.mask &= ~(MASK_TOP_LEFT | MASK_TOP_RIGHT);
+               }
+
+               if (setup->quad.mask) {
+                  setup->quad.x0 = ix;
+                  setup->quad.y0 = iy;
+                  clip_emit_quad(setup);
+               }
+            }
+         }
+      }
+   }
+}
+
+
+
+static void setup_begin( struct draw_stage *stage )
+{
+   struct setup_stage *setup = setup_stage(stage);
+
+   setup->quad.nr_attrs = setup->softpipe->nr_frag_attrs;
+}
+
+
+static void setup_end( struct draw_stage *stage )
+{
+}
+
+
+static void reset_stipple_counter( struct draw_stage *stage )
+{
+   struct setup_stage *setup = setup_stage(stage);
+   setup->softpipe->line_stipple_counter = 0;
+}
+
+
+/**
+ * Create a new primitive setup/render stage.
+ */
+struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe )
+{
+   struct setup_stage *setup = CALLOC_STRUCT(setup_stage);
+
+   setup->softpipe = softpipe;
+   setup->stage.draw = softpipe->draw;
+   setup->stage.begin = setup_begin;
+   setup->stage.point = setup_point;
+   setup->stage.line = setup_line;
+   setup->stage.tri = setup_tri;
+   setup->stage.end = setup_end;
+   setup->stage.reset_stipple_counter = reset_stipple_counter;
+
+   setup->quad.coef = setup->coef;
+
+   return &setup->stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.h b/src/mesa/pipe/softpipe/sp_prim_setup.h
new file mode 100644 (file)
index 0000000..e5abefc
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * 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.
+ */
+
+
+#ifndef SP_PRIM_SETUP_H
+#define SP_PRIM_SETUP_H
+
+
+/* Vertices are just an array of floats, with all the attributes
+ * packed.  We currently assume a layout like:
+ *
+ * attr[0][0..3] - window position
+ * attr[1..n][0..3] - remaining attributes.
+ *
+ * Attributes are assumed to be 4 floats wide but are packed so that
+ * all the enabled attributes run contiguously.
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#if 0
+#include "s_tri_public.h"
+#endif
+#include "s_context.h"
+
+
+extern struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe );
+
+
+#if 0 /* UNUSED? */
+struct tri_context;
+struct fp_context;
+struct be_context;
+
+/* Note the rasterizer does not take a GLcontext argument.  This is
+ * deliberate.
+ */
+struct tri_context *tri_create_context( GLcontext *ctx );
+
+void tri_destroy_context( struct tri_context *tri );
+
+void tri_set_fp_context( struct tri_context *tri,
+                        struct fp_context *fp,
+                        void (*fp_run)( struct fp_context *fp,
+                                        const struct fp_inputs *,
+                                        struct fp_outputs * ));
+
+
+void tri_set_be_context( struct tri_context *tri,
+                        struct be_context *be,
+                        void (*be_run)( struct be_context *be,
+                                        const struct fp_outputs * ));
+
+void tri_set_attribs( struct tri_context *tri,
+                     const struct attr_info *info,
+                     GLuint nr_attrib );
+
+void tri_set_backface( struct tri_context *tri,
+                      GLfloat backface );
+                                              
+void tri_set_scissor( struct tri_context *tri,
+                     GLint x,
+                     GLint y,
+                     GLuint width,
+                     GLuint height,
+                     GLboolean enabled );
+
+void tri_set_stipple( struct tri_context *tri,
+                     const GLuint *pattern,
+                     GLboolean enabled );
+
+/* Unfilled triangles will be handled elsewhere (higher in the
+ * pipeline), as will things like stipple (lower in the pipeline).
+ */
+
+void tri_triangle( struct tri_context *tri,
+                  const struct vertex *v0,
+                  const struct vertex *v1,
+                  const struct vertex *v2 );
+
+/* TODO: rasterize_line, rasterize_point?? 
+ * How will linestipple work?
+ */
+
+
+#ifdef SETUP_PRIVATE
+
+GLboolean tri_setup( struct tri_context *tri,
+                      const struct vertex *v0,
+                      const struct vertex *v1,
+                      const struct vertex *v2 );
+
+void tri_rasterize( struct tri_context *tri );
+void tri_rasterize_spans( struct tri_context *tri );
+
+#endif
+
+
+#endif
+
+#endif /* SP_PRIM_SETUP_H */
diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c
new file mode 100644 (file)
index 0000000..0053b16
--- /dev/null
@@ -0,0 +1,71 @@
+
+
+#include "sp_context.h"
+
+
+
+void
+sp_build_quad_pipeline(struct softpipe_context *sp)
+{
+   /* build up the pipeline in reverse order... */
+
+   sp->quad.first = sp->quad.output;
+
+   if (sp->blend.colormask != 0xf) {
+      sp->quad.colormask->next = sp->quad.first;
+      sp->quad.first = sp->quad.colormask;
+   }
+
+   if (sp->blend.blend_enable) {
+      sp->quad.blend->next = sp->quad.first;
+      sp->quad.first = sp->quad.blend;
+   }
+
+   if (sp->framebuffer.num_cbufs == 1) {
+      /* the usual case: write to exactly one colorbuf */
+      sp->cbuf = sp->framebuffer.cbufs[0];
+   }
+   else {
+      /* insert bufloop stage */
+      sp->quad.bufloop->next = sp->quad.first;
+      sp->quad.first = sp->quad.bufloop;
+   }
+
+   if (sp->depth_test.occlusion_count) {
+      sp->quad.occlusion->next = sp->quad.first;
+      sp->quad.first = sp->quad.occlusion;
+   }
+
+   if (sp->setup.poly_smooth ||
+       sp->setup.line_smooth ||
+       sp->setup.point_smooth) {
+      sp->quad.coverage->next = sp->quad.first;
+      sp->quad.first = sp->quad.coverage;
+   }
+
+   if (   sp->stencil.front_enabled
+       || sp->stencil.front_enabled) {
+      sp->quad.stencil_test->next = sp->quad.first;
+      sp->quad.first = sp->quad.stencil_test;
+   }
+   else if (sp->depth_test.enabled) {
+      sp->quad.depth_test->next = sp->quad.first;
+      sp->quad.first = sp->quad.depth_test;
+   }
+
+   if (sp->alpha_test.enabled) {
+      sp->quad.alpha_test->next = sp->quad.first;
+      sp->quad.first = sp->quad.alpha_test;
+   }
+
+   /* XXX always enable shader? */
+   if (1) {
+      sp->quad.shade->next = sp->quad.first;
+      sp->quad.first = sp->quad.shade;
+   }
+
+   if (sp->setup.poly_stipple_enable) {
+      sp->quad.polygon_stipple->next = sp->quad.first;
+      sp->quad.first = sp->quad.polygon_stipple;
+   }
+}
diff --git a/src/mesa/pipe/softpipe/sp_quad.h b/src/mesa/pipe/softpipe/sp_quad.h
new file mode 100644 (file)
index 0000000..72a9981
--- /dev/null
@@ -0,0 +1,65 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef SP_QUAD_H
+#define SP_QUAD_H
+
+
+struct softpipe_context;
+struct quad_header;
+
+
+struct quad_stage {
+   struct softpipe_context *softpipe;
+
+   struct quad_stage *next;
+
+   /** the stage action */
+   void (*run)(struct quad_stage *qs, struct quad_header *quad);
+};
+
+
+struct quad_stage *sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_alpha_test_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe );
+
+void sp_build_quad_pipeline(struct softpipe_context *sp);
+
+void sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad);
+
+#endif /* SP_QUAD_H */
diff --git a/src/mesa/pipe/softpipe/sp_quad_alpha_test.c b/src/mesa/pipe/softpipe/sp_quad_alpha_test.c
new file mode 100644 (file)
index 0000000..8c28a82
--- /dev/null
@@ -0,0 +1,94 @@
+
+/**
+ * quad alpha test
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_quad.h"
+#include "pipe/p_defines.h"
+
+
+static void
+alpha_test_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+   const GLfloat ref = softpipe->alpha_test.ref;
+   GLuint passMask = 0x0, j;
+
+   switch (softpipe->alpha_test.func) {
+   case PIPE_FUNC_NEVER:
+      quad->mask = 0x0;
+      break;
+   case PIPE_FUNC_LESS:
+      /*
+       * If mask were an array [4] we could do this SIMD-style:
+       * passMask = (quad->outputs.color[3] <= vec4(ref));
+       */
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (quad->outputs.color[3][j] < ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_EQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (quad->outputs.color[3][j] == ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_LEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (quad->outputs.color[3][j] <= ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_GREATER:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (quad->outputs.color[3][j] > ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_NOTEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (quad->outputs.color[3][j] != ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_GEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (quad->outputs.color[3][j] >= ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_ALWAYS:
+      passMask = MASK_ALL;
+      break;
+   default:
+      abort();
+   }
+
+   quad->mask &= passMask;
+
+   if (quad->mask)
+      qs->next->run(qs->next, quad);
+}
+
+
+struct quad_stage *
+sp_quad_alpha_test_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = alpha_test_quad;
+
+   return stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_quad_blend.c b/src/mesa/pipe/softpipe/sp_quad_blend.c
new file mode 100644 (file)
index 0000000..3d097ae
--- /dev/null
@@ -0,0 +1,395 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/**
+ * quad blending
+ * \author Brian Paul
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "macros.h"
+#include "pipe/p_defines.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_surface.h"
+#include "sp_quad.h"
+
+
+#define VEC4_COPY(DST, SRC) \
+do { \
+    DST[0] = SRC[0]; \
+    DST[1] = SRC[1]; \
+    DST[2] = SRC[2]; \
+    DST[3] = SRC[3]; \
+} while(0)
+
+#define VEC4_SCALAR(DST, SRC) \
+do { \
+    DST[0] = SRC; \
+    DST[1] = SRC; \
+    DST[2] = SRC; \
+    DST[3] = SRC; \
+} while(0)
+
+#define VEC4_ADD(SUM, A, B) \
+do { \
+   SUM[0] = A[0] + B[0]; \
+   SUM[1] = A[1] + B[1]; \
+   SUM[2] = A[2] + B[2]; \
+   SUM[3] = A[3] + B[3]; \
+} while (0)
+
+#define VEC4_SUB(SUM, A, B) \
+do { \
+   SUM[0] = A[0] - B[0]; \
+   SUM[1] = A[1] - B[1]; \
+   SUM[2] = A[2] - B[2]; \
+   SUM[3] = A[3] - B[3]; \
+} while (0)
+
+#define VEC4_MUL(SUM, A, B) \
+do { \
+   SUM[0] = A[0] * B[0]; \
+   SUM[1] = A[1] * B[1]; \
+   SUM[2] = A[2] * B[2]; \
+   SUM[3] = A[3] * B[3]; \
+} while (0)
+
+#define VEC4_MIN(SUM, A, B) \
+do { \
+   SUM[0] = (A[0] < B[0]) ? A[0] : B[0]; \
+   SUM[1] = (A[1] < B[1]) ? A[1] : B[1]; \
+   SUM[2] = (A[2] < B[2]) ? A[2] : B[2]; \
+   SUM[3] = (A[3] < B[3]) ? A[3] : B[3]; \
+} while (0)
+
+#define VEC4_MAX(SUM, A, B) \
+do { \
+   SUM[0] = (A[0] > B[0]) ? A[0] : B[0]; \
+   SUM[1] = (A[1] > B[1]) ? A[1] : B[1]; \
+   SUM[2] = (A[2] > B[2]) ? A[2] : B[2]; \
+   SUM[3] = (A[3] > B[3]) ? A[3] : B[3]; \
+} while (0)
+
+
+
+static void
+blend_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   static const GLfloat zero[4] = { 0, 0, 0, 0 };
+   static const GLfloat one[4] = { 1, 1, 1, 1 };
+   struct softpipe_context *softpipe = qs->softpipe;
+   struct softpipe_surface *sps = softpipe_surface(softpipe->cbuf);
+   GLfloat source[4][QUAD_SIZE], dest[4][QUAD_SIZE];
+   
+   /* get colors from framebuffer */
+   sps->read_quad_f_swz(sps, quad->x0, quad->y0, dest);
+
+   /*
+    * Compute src/first term RGB
+    */
+   switch (softpipe->blend.rgb_src_factor) {
+   case PIPE_BLENDFACTOR_ONE:
+      VEC4_COPY(source[0], quad->outputs.color[0]); /* R */
+      VEC4_COPY(source[1], quad->outputs.color[1]); /* G */
+      VEC4_COPY(source[2], quad->outputs.color[2]); /* B */
+      break;
+   case PIPE_BLENDFACTOR_SRC_COLOR:
+      VEC4_MUL(source[0], quad->outputs.color[0], quad->outputs.color[0]); /* R */
+      VEC4_MUL(source[1], quad->outputs.color[1], quad->outputs.color[1]); /* G */
+      VEC4_MUL(source[2], quad->outputs.color[2], quad->outputs.color[2]); /* B */
+      break;
+   case PIPE_BLENDFACTOR_SRC_ALPHA:
+      {
+         const GLfloat *alpha = quad->outputs.color[3];
+         VEC4_MUL(source[0], quad->outputs.color[0], alpha); /* R */
+         VEC4_MUL(source[1], quad->outputs.color[1], alpha); /* G */
+         VEC4_MUL(source[2], quad->outputs.color[2], alpha); /* B */
+      }
+      break;
+   case PIPE_BLENDFACTOR_DST_COLOR:
+      VEC4_MUL(source[0], quad->outputs.color[0], dest[0]); /* R */
+      VEC4_MUL(source[1], quad->outputs.color[1], dest[1]); /* G */
+      VEC4_MUL(source[2], quad->outputs.color[2], dest[2]); /* B */
+      break;
+   case PIPE_BLENDFACTOR_DST_ALPHA:
+      {
+         const GLfloat *alpha = dest[3];
+         VEC4_MUL(source[0], quad->outputs.color[0], alpha); /* R */
+         VEC4_MUL(source[1], quad->outputs.color[1], alpha); /* G */
+         VEC4_MUL(source[2], quad->outputs.color[2], alpha); /* B */
+      }
+      break;
+   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+      assert(0); /* to do */
+      break;
+   case PIPE_BLENDFACTOR_CONST_COLOR:
+      {
+         GLfloat comp[4];
+         VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
+         VEC4_MUL(source[0], quad->outputs.color[0], comp); /* R */
+         VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
+         VEC4_MUL(source[1], quad->outputs.color[1], comp); /* G */
+         VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
+         VEC4_MUL(source[2], quad->outputs.color[2], comp); /* B */
+      }
+      break;
+   case PIPE_BLENDFACTOR_CONST_ALPHA:
+      {
+         GLfloat alpha[4];
+         VEC4_SCALAR(alpha, softpipe->blend_color.color[3]);
+         VEC4_MUL(source[0], quad->outputs.color[0], alpha); /* R */
+         VEC4_MUL(source[1], quad->outputs.color[1], alpha); /* G */
+         VEC4_MUL(source[2], quad->outputs.color[2], alpha); /* B */
+      }
+      break;
+   case PIPE_BLENDFACTOR_SRC1_COLOR:
+      assert(0); /* to do */
+      break;
+   case PIPE_BLENDFACTOR_SRC1_ALPHA:
+      assert(0); /* to do */
+      break;
+   case PIPE_BLENDFACTOR_ZERO:
+      VEC4_COPY(source[0], zero); /* R */
+      VEC4_COPY(source[1], zero); /* G */
+      VEC4_COPY(source[2], zero); /* B */
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+      {
+         GLfloat inv_comp[4];
+         VEC4_SUB(inv_comp, one, quad->outputs.color[0]); /* R */
+         VEC4_MUL(source[0], quad->outputs.color[0], inv_comp); /* R */
+         VEC4_SUB(inv_comp, one, quad->outputs.color[1]); /* G */
+         VEC4_MUL(source[1], quad->outputs.color[1], inv_comp); /* G */
+         VEC4_SUB(inv_comp, one, quad->outputs.color[2]); /* B */
+         VEC4_MUL(source[2], quad->outputs.color[2], inv_comp); /* B */
+      }
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+      {
+         GLfloat inv_alpha[4];
+         VEC4_SUB(inv_alpha, one, quad->outputs.color[3]);
+         VEC4_MUL(source[0], quad->outputs.color[0], inv_alpha); /* R */
+         VEC4_MUL(source[1], quad->outputs.color[1], inv_alpha); /* G */
+         VEC4_MUL(source[2], quad->outputs.color[2], inv_alpha); /* B */
+      }
+      break;
+   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+      {
+         GLfloat inv_alpha[4];
+         VEC4_SUB(inv_alpha, one, dest[3]);
+         VEC4_MUL(source[0], quad->outputs.color[0], inv_alpha); /* R */
+         VEC4_MUL(source[1], quad->outputs.color[1], inv_alpha); /* G */
+         VEC4_MUL(source[2], quad->outputs.color[2], inv_alpha); /* B */
+      }
+      break;
+   case PIPE_BLENDFACTOR_INV_DST_COLOR:
+      {
+         GLfloat inv_comp[4];
+         VEC4_SUB(inv_comp, one, dest[0]); /* R */
+         VEC4_MUL(source[0], quad->outputs.color[0], inv_comp); /* R */
+         VEC4_SUB(inv_comp, one, dest[1]); /* G */
+         VEC4_MUL(source[1], quad->outputs.color[1], inv_comp); /* G */
+         VEC4_SUB(inv_comp, one, dest[2]); /* B */
+         VEC4_MUL(source[2], quad->outputs.color[2], inv_comp); /* B */
+      }
+      break;
+   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+      {
+         GLfloat inv_comp[4];
+         /* R */
+         VEC4_SCALAR(inv_comp, 1.0 - softpipe->blend_color.color[0]);
+         VEC4_MUL(source[0], quad->outputs.color[0], inv_comp);
+         /* G */
+         VEC4_SCALAR(inv_comp, 1.0 - softpipe->blend_color.color[1]);
+         VEC4_MUL(source[1], quad->outputs.color[1], inv_comp);
+         /* B */
+         VEC4_SCALAR(inv_comp, 1.0 - softpipe->blend_color.color[2]);
+         VEC4_MUL(source[2], quad->outputs.color[2], inv_comp);
+      }
+      break;
+   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+      {
+         GLfloat alpha[4], inv_alpha[4];
+         VEC4_SCALAR(alpha, 1.0 - softpipe->blend_color.color[3]);
+         VEC4_MUL(source[0], quad->outputs.color[0], inv_alpha); /* R */
+         VEC4_MUL(source[1], quad->outputs.color[1], inv_alpha); /* G */
+         VEC4_MUL(source[2], quad->outputs.color[2], inv_alpha); /* B */
+      }
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+      assert(0); /* to do */
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+      assert(0); /* to do */
+      break;
+   default:
+      abort();
+   }
+   
+   /*
+    * Compute src/first term A
+    */
+   switch (softpipe->blend.alpha_src_factor) {
+   case PIPE_BLENDFACTOR_ONE:
+      VEC4_COPY(source[3], quad->outputs.color[3]); /* A */
+      break;
+   case PIPE_BLENDFACTOR_SRC_ALPHA:
+      {
+         const GLfloat *alpha = quad->outputs.color[3];
+         VEC4_MUL(source[3], quad->outputs.color[3], alpha); /* A */
+      }
+      break;
+   case PIPE_BLENDFACTOR_ZERO:
+      VEC4_COPY(source[3], zero); /* A */
+      break;
+      /* XXX fill in remaining terms */
+   default:
+      abort();
+   }
+   
+   
+   /*
+    * Compute dest/second term RGB
+    */
+   switch (softpipe->blend.rgb_dst_factor) {
+   case PIPE_BLENDFACTOR_ONE:
+      /* dest = dest * 1   NO-OP, leave dest as-is */
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+      {
+         GLfloat one_minus_alpha[QUAD_SIZE];
+         VEC4_SUB(one_minus_alpha, one, quad->outputs.color[3]);
+         VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
+         VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
+         VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
+      }
+      break;
+   case PIPE_BLENDFACTOR_ZERO:
+      VEC4_COPY(dest[0], zero); /* R */
+      VEC4_COPY(dest[1], zero); /* G */
+      VEC4_COPY(dest[2], zero); /* B */
+      break;
+      /* XXX fill in remaining terms */
+   default:
+      abort();
+   }
+   
+   /*
+    * Compute dest/second term A
+    */
+   switch (softpipe->blend.alpha_dst_factor) {
+   case PIPE_BLENDFACTOR_ONE:
+      /* dest = dest * 1   NO-OP, leave dest as-is */
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+      {
+         GLfloat one_minus_alpha[QUAD_SIZE];
+         VEC4_SUB(one_minus_alpha, one, quad->outputs.color[3]);
+         VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */
+      }
+      break;
+   case PIPE_BLENDFACTOR_ZERO:
+      VEC4_COPY(dest[3], zero); /* A */
+      break;
+      /* XXX fill in remaining terms */
+   default:
+      abort();
+   }
+   
+   /*
+    * Combine RGB terms
+    */
+   switch (softpipe->blend.rgb_func) {
+   case PIPE_BLEND_ADD:
+      VEC4_ADD(quad->outputs.color[0], source[0], dest[0]); /* R */
+      VEC4_ADD(quad->outputs.color[1], source[1], dest[1]); /* G */
+      VEC4_ADD(quad->outputs.color[2], source[2], dest[2]); /* B */
+      break;
+   case PIPE_BLEND_SUBTRACT:
+      VEC4_SUB(quad->outputs.color[0], source[0], dest[0]); /* R */
+      VEC4_SUB(quad->outputs.color[1], source[1], dest[1]); /* G */
+      VEC4_SUB(quad->outputs.color[2], source[2], dest[2]); /* B */
+      break;
+   case PIPE_BLEND_REVERSE_SUBTRACT:
+      VEC4_SUB(quad->outputs.color[0], dest[0], source[0]); /* R */
+      VEC4_SUB(quad->outputs.color[1], dest[1], source[1]); /* G */
+      VEC4_SUB(quad->outputs.color[2], dest[2], source[2]); /* B */
+      break;
+   case PIPE_BLEND_MIN:
+      VEC4_MIN(quad->outputs.color[0], source[0], dest[0]); /* R */
+      VEC4_MIN(quad->outputs.color[1], source[1], dest[1]); /* G */
+      VEC4_MIN(quad->outputs.color[2], source[2], dest[2]); /* B */
+      break;
+   case PIPE_BLEND_MAX:
+      VEC4_MAX(quad->outputs.color[0], source[0], dest[0]); /* R */
+      VEC4_MAX(quad->outputs.color[1], source[1], dest[1]); /* G */
+      VEC4_MAX(quad->outputs.color[2], source[2], dest[2]); /* B */
+      break;
+   default:
+      abort();
+   }
+   
+   /*
+    * Combine A terms
+    */
+   switch (softpipe->blend.alpha_func) {
+   case PIPE_BLEND_ADD:
+      VEC4_ADD(quad->outputs.color[3], source[3], dest[3]); /* A */
+      break;
+   case PIPE_BLEND_SUBTRACT:
+      VEC4_SUB(quad->outputs.color[3], source[3], dest[3]); /* A */
+      break;
+   case PIPE_BLEND_REVERSE_SUBTRACT:
+      VEC4_SUB(quad->outputs.color[3], dest[3], source[3]); /* A */
+      break;
+   case PIPE_BLEND_MIN:
+      VEC4_MIN(quad->outputs.color[3], source[3], dest[3]); /* A */
+      break;
+   case PIPE_BLEND_MAX:
+      VEC4_MAX(quad->outputs.color[3], source[3], dest[3]); /* A */
+   default:
+      abort();
+   }
+   
+   /* pass blended quad to next stage */
+   qs->next->run(qs->next, quad);
+}
+
+
+
+
+struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = blend_quad;
+
+   return stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_quad_bufloop.c b/src/mesa/pipe/softpipe/sp_quad_bufloop.c
new file mode 100644 (file)
index 0000000..be32d02
--- /dev/null
@@ -0,0 +1,62 @@
+
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_surface.h"
+#include "sp_quad.h"
+
+
+/**
+ * Loop over colorbuffers, passing quad to next stage each time.
+ */
+static void
+cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+   GLfloat tmp[4][QUAD_SIZE];
+   GLuint i;
+
+   assert(sizeof(quad->outputs.color) == sizeof(tmp));
+   assert(softpipe->framebuffer.num_cbufs <= PIPE_MAX_COLOR_BUFS);
+
+   /* make copy of original colors since they can get modified
+    * by blending and masking.
+    * XXX we won't have to do this if the fragment program actually emits
+    * N separate colors and we're drawing to N color buffers (MRT).
+    * But if we emitted one color and glDrawBuffer(GL_FRONT_AND_BACK) is
+    * in effect, we need to save/restore colors like this.
+    */
+   memcpy(tmp, quad->outputs.color, sizeof(tmp));
+
+   for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
+      /* set current cbuffer */
+      softpipe->cbuf = softpipe->framebuffer.cbufs[i];
+
+      /* pass blended quad to next stage */
+      qs->next->run(qs->next, quad);
+
+      /* restore quad's colors for next buffer */
+      memcpy(quad->outputs.color, tmp, sizeof(tmp));
+   }
+
+   softpipe->cbuf = NULL; /* prevent accidental use */
+}
+
+
+/**
+ * Create the colorbuffer loop stage.
+ * This is used to implement multiple render targets and GL_FRONT_AND_BACK
+ * rendering.
+ */
+struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = cbuf_loop_quad;
+
+   return stage;
+}
+
diff --git a/src/mesa/pipe/softpipe/sp_quad_colormask.c b/src/mesa/pipe/softpipe/sp_quad_colormask.c
new file mode 100644 (file)
index 0000000..fff6efa
--- /dev/null
@@ -0,0 +1,84 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  quad colormask stage
+ * \author Brian Paul
+ */
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "pipe/p_defines.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_surface.h"
+#include "sp_quad.h"
+
+
+
+static void
+colormask_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+   struct softpipe_surface *sps = softpipe_surface(softpipe->cbuf);
+   GLfloat dest[4][QUAD_SIZE];
+   
+   sps->read_quad_f_swz(sps, quad->x0, quad->y0, dest);
+
+   /* R */
+   if (!(softpipe->blend.colormask & PIPE_MASK_R))
+       COPY_4FV(quad->outputs.color[0], dest[0]);
+
+   /* G */
+   if (!(softpipe->blend.colormask & PIPE_MASK_G))
+       COPY_4FV(quad->outputs.color[1], dest[1]);
+
+   /* B */
+   if (!(softpipe->blend.colormask & PIPE_MASK_B))
+       COPY_4FV(quad->outputs.color[2], dest[2]);
+
+   /* A */
+   if (!(softpipe->blend.colormask & PIPE_MASK_A))
+       COPY_4FV(quad->outputs.color[3], dest[3]);
+
+   /* pass quad to next stage */
+   qs->next->run(qs->next, quad);
+}
+
+
+
+
+struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = colormask_quad;
+
+   return stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_quad_coverage.c b/src/mesa/pipe/softpipe/sp_quad_coverage.c
new file mode 100644 (file)
index 0000000..cdd8890
--- /dev/null
@@ -0,0 +1,74 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+
+/**
+ * \brief  Apply AA coverage to quad alpha valus
+ * \author  Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/macros.h"
+#include "pipe/p_defines.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_quad.h"
+
+
+/**
+ * Multiply quad's alpha values by the fragment coverage.
+ */
+static void
+coverage_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+
+   if ((softpipe->setup.poly_smooth && quad->prim == PRIM_TRI) ||
+       (softpipe->setup.line_smooth && quad->prim == PRIM_LINE) ||
+       (softpipe->setup.point_smooth && quad->prim == PRIM_POINT)) {
+      GLuint j;
+      for (j = 0; j < QUAD_SIZE; j++) {
+         assert(quad->coverage[j] >= 0.0);
+         assert(quad->coverage[j] <= 1.0);
+         quad->outputs.color[3][j] *= quad->coverage[j];
+      }
+   }
+
+   qs->next->run(qs->next, quad);
+}
+
+
+struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = coverage_quad;
+
+   return stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c
new file mode 100644 (file)
index 0000000..a26bd51
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * 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.
+ */
+
+/**
+ * \brief  Quad depth testing
+ */
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "pipe/p_defines.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_surface.h"
+#include "sp_quad.h"
+
+
+/**
+ * Do depth testing for a quad.
+ * Not static since it's used by the stencil code.
+ */
+void
+sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+   struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.zbuf);
+   GLuint bzzzz[QUAD_SIZE];  /**< Z values fetched from depth buffer */
+   GLuint qzzzz[QUAD_SIZE];  /**< Z values from the quad */
+   GLuint zmask = 0;
+   GLuint j;
+   GLfloat scale;
+
+   assert(sps); /* shouldn't get here if there's no zbuffer */
+
+   /*
+    * To increase efficiency, we should probably have multiple versions
+    * of this function that are specifically for Z16, Z32 and FP Z buffers.
+    * Try to effectively do that with codegen...
+    */
+   if (sps->surface.format == PIPE_FORMAT_U_Z16)
+      scale = 65535.0;
+   else if (sps->surface.format == PIPE_FORMAT_Z24_S8)
+      scale = (float) ((1 << 24) - 1);
+   else
+      assert(0);  /* XXX fix this someday */
+
+   /*
+    * Convert quad's float depth values to int depth values.
+    * If the Z buffer stores integer values, we _have_ to do the depth
+    * compares with integers (not floats).  Otherwise, the float->int->float
+    * conversion of Z values (which isn't an identity function) will cause
+    * Z-fighting errors.
+    */
+   for (j = 0; j < QUAD_SIZE; j++) {
+      qzzzz[j] = (GLuint) (quad->outputs.depth[j] * scale);
+   }
+
+   /* get zquad from zbuffer */
+   sps->read_quad_z(sps, quad->x0, quad->y0, bzzzz);
+
+   switch (softpipe->depth_test.func) {
+   case PIPE_FUNC_NEVER:
+      /* zmask = 0 */
+      break;
+   case PIPE_FUNC_LESS:
+      /* Note this is pretty much a single sse or cell instruction.  
+       * Like this:  quad->mask &= (quad->outputs.depth < zzzz);
+       */
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] < bzzzz[j]) 
+           zmask |= 1 << j;
+      }
+      break;
+   case PIPE_FUNC_EQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] == bzzzz[j]) 
+           zmask |= 1 << j;
+      }
+      break;
+   case PIPE_FUNC_LEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] <= bzzzz[j]) 
+           zmask |= (1 << j);
+      }
+      break;
+   case PIPE_FUNC_GREATER:
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] > bzzzz[j]) 
+           zmask |= (1 << j);
+      }
+      break;
+   case PIPE_FUNC_NOTEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] != bzzzz[j]) 
+           zmask |= (1 << j);
+      }
+      break;
+   case PIPE_FUNC_GEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (qzzzz[j] >= bzzzz[j]) 
+           zmask |= (1 << j);
+      }
+      break;
+   case PIPE_FUNC_ALWAYS:
+      zmask = MASK_ALL;
+      break;
+   default:
+      abort();
+   }
+
+   quad->mask &= zmask;
+
+   if (softpipe->depth_test.writemask) {
+      
+      /* This is also efficient with sse / spe instructions: 
+       */
+      for (j = 0; j < QUAD_SIZE; j++) {
+        if (quad->mask & (1 << j)) {
+           bzzzz[j] = qzzzz[j];
+        }
+      }
+
+      /* write updated zquad to zbuffer */
+      sps->write_quad_z(sps, quad->x0, quad->y0, bzzzz);
+   }
+}
+
+
+static void
+depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   sp_depth_test_quad(qs, quad);
+
+   if (quad->mask)
+      qs->next->run(qs->next, quad);
+}
+
+
+
+
+struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = depth_test_quad;
+
+   return stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c
new file mode 100644 (file)
index 0000000..d4acf40
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * 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.
+ */
+
+/* Vertices are just an array of floats, with all the attributes
+ * packed.  We currently assume a layout like:
+ *
+ * attr[0][0..3] - window position
+ * attr[1..n][0..3] - remaining attributes.
+ *
+ * Attributes are assumed to be 4 floats wide but are packed so that
+ * all the enabled attributes run contiguously.
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_quad.h"
+#include "core/tgsi_core.h"
+
+#if defined __GNUC__
+#define ALIGNED_ATTRIBS 1
+#else
+#define ALIGNED_ATTRIBS 0
+#endif
+
+struct exec_machine {
+   const struct setup_coefficient *coef; /**< will point to quad->coef */
+
+#if ALIGNED_ATTRIBS
+   GLfloat attr[FRAG_ATTRIB_MAX][NUM_CHANNELS][QUAD_SIZE] __attribute__(( aligned( 16 ) ));
+#else
+   GLfloat attr[FRAG_ATTRIB_MAX][NUM_CHANNELS][QUAD_SIZE];
+#endif
+};
+
+
+/**
+ * Compute quad's attributes values, as constants (GL_FLAT shading).
+ */
+static INLINE void cinterp( struct exec_machine *exec,
+                           GLuint attrib,
+                           GLuint i )
+{
+   GLuint j;
+
+   for (j = 0; j < QUAD_SIZE; j++) {
+      exec->attr[attrib][i][j] = exec->coef[attrib].a0[i];
+   }
+}
+
+
+/**
+ * Compute quad's attribute values by linear interpolation.
+ *
+ * Push into the fp:
+ * 
+ *   INPUT[attr] = MAD COEF_A0[attr], COEF_DADX[attr], INPUT_WPOS.xxxx
+ *   INPUT[attr] = MAD INPUT[attr],   COEF_DADY[attr], INPUT_WPOS.yyyy
+ */
+static INLINE void linterp( struct exec_machine *exec,
+                           GLuint attrib,
+                           GLuint i )
+{
+   GLuint j;
+
+   for (j = 0; j < QUAD_SIZE; j++) {
+      const GLfloat x = exec->attr[FRAG_ATTRIB_WPOS][0][j];
+      const GLfloat y = exec->attr[FRAG_ATTRIB_WPOS][1][j];
+      exec->attr[attrib][i][j] = (exec->coef[attrib].a0[i] +
+                                 exec->coef[attrib].dadx[i] * x + 
+                                 exec->coef[attrib].dady[i] * y);
+   }
+}
+
+
+/**
+ * Compute quad's attribute values by linear interpolation with
+ * perspective correction.
+ *
+ * Push into the fp:
+ * 
+ *   INPUT[attr] = MAD COEF_DADX[attr], INPUT_WPOS.xxxx, COEF_A0[attr]
+ *   INPUT[attr] = MAD COEF_DADY[attr], INPUT_WPOS.yyyy, INPUT[attr]
+ *   TMP         = RCP INPUT_WPOS.w
+ *   INPUT[attr] = MUL INPUT[attr], TMP.xxxx
+ *
+ */
+static INLINE void pinterp( struct exec_machine *exec,
+                           GLuint attrib,
+                           GLuint i )
+{
+   GLuint j;
+
+   for (j = 0; j < QUAD_SIZE; j++) {
+      const GLfloat x = exec->attr[FRAG_ATTRIB_WPOS][0][j];
+      const GLfloat y = exec->attr[FRAG_ATTRIB_WPOS][1][j];
+      /* FRAG_ATTRIB_WPOS.w here is really 1/w */
+      const GLfloat w = 1.0 / exec->attr[FRAG_ATTRIB_WPOS][3][j];
+      exec->attr[attrib][i][j] = ((exec->coef[attrib].a0[i] +
+                                  exec->coef[attrib].dadx[i] * x + 
+                                  exec->coef[attrib].dady[i] * y) * w);
+   }
+}
+
+
+
+/* This should be done by the fragment shader execution unit (code
+ * generated from the decl instructions).  Do it here for now.
+ */
+static void
+shade_quad( struct quad_stage *qs, struct quad_header *quad )
+{
+   const struct softpipe_context *softpipe = qs->softpipe;
+   struct exec_machine exec;
+   const GLfloat fx = quad->x0;
+   const GLfloat fy = quad->y0;
+   GLuint attr, i;
+
+   exec.coef = quad->coef;
+
+   /* Position:
+    */
+   exec.attr[FRAG_ATTRIB_WPOS][0][0] = fx;
+   exec.attr[FRAG_ATTRIB_WPOS][0][1] = fx + 1.0;
+   exec.attr[FRAG_ATTRIB_WPOS][0][2] = fx;
+   exec.attr[FRAG_ATTRIB_WPOS][0][3] = fx + 1.0;
+
+   exec.attr[FRAG_ATTRIB_WPOS][1][0] = fy;
+   exec.attr[FRAG_ATTRIB_WPOS][1][1] = fy;
+   exec.attr[FRAG_ATTRIB_WPOS][1][2] = fy + 1.0;
+   exec.attr[FRAG_ATTRIB_WPOS][1][3] = fy + 1.0;
+
+   /* Z and W are done by linear interpolation */
+   if (softpipe->need_z) {
+      linterp(&exec, 0, 2);   /* attr[0].z */
+   }
+
+   if (softpipe->need_w) {
+      linterp(&exec, 0, 3);  /* attr[0].w */
+      /*invert(&exec, 0, 3);*/
+   }
+
+   /* Interpolate all the remaining attributes.  This will get pushed
+    * into the fragment program's responsibilities at some point.
+    * Start at 1 to skip fragment position attribute (computed above).
+    */
+   for (attr = 1; attr < quad->nr_attrs; attr++) {
+      switch (softpipe->interp[attr]) {
+      case INTERP_CONSTANT:
+        for (i = 0; i < NUM_CHANNELS; i++)
+           cinterp(&exec, attr, i);
+        break;
+
+      case INTERP_LINEAR:
+        for (i = 0; i < NUM_CHANNELS; i++)
+           linterp(&exec, attr, i);
+        break;
+
+      case INTERP_PERSPECTIVE:
+        for (i = 0; i < NUM_CHANNELS; i++)
+           pinterp(&exec, attr, i);
+        break;
+      }
+   }
+
+#if 1
+   /*softpipe->run_fs( tri->fp, quad, &tri->outputs );*/
+
+   {
+      struct tgsi_exec_machine machine;
+      struct tgsi_exec_vector outputs[FRAG_ATTRIB_MAX + 1];
+      struct tgsi_exec_vector *aoutputs;
+      GLuint i;
+
+#if !ALIGNED_ATTRIBS
+      struct tgsi_exec_vector inputs[FRAG_ATTRIB_MAX + 1];
+      struct tgsi_exec_vector *ainputs;
+#endif
+
+#ifdef DEBUG
+      memset(&machine, 0, sizeof(machine));
+#endif
+
+      /* init machine state */
+      tgsi_exec_machine_init(
+         &machine,
+         softpipe->fs.tokens );
+
+      /* Consts does not require 16 byte alignment. */
+      machine.Consts = softpipe->fs.constants->constant;
+
+      aoutputs = (struct tgsi_exec_vector *) tgsi_align_128bit( outputs );
+      machine.Outputs = aoutputs;
+
+      assert( sizeof( struct tgsi_exec_vector ) == sizeof( exec.attr[0] ) );
+
+#if ALIGNED_ATTRIBS
+      machine.Inputs = (struct tgsi_exec_vector *) exec.attr;
+
+      for (i = 0; i < softpipe->nr_attrs; i++) {
+         /* Make sure fp_attr_to_slot[] is an identity transform. */
+         assert( softpipe->fp_attr_to_slot[i] == i );
+      }
+#else
+      ainputs = (struct tgsi_exec_vector *) tgsi_align_128bit( inputs );
+      machine.Inputs = ainputs;
+
+      /* load input registers */
+      for (i = 0; i < softpipe->nr_attrs; i++) {
+         /* Make sure fp_attr_to_slot[] is an identity transform. */
+         assert( softpipe->fp_attr_to_slot[i] == i );
+
+         memcpy(
+            &ainputs[i],
+            exec.attr[i],
+            sizeof( ainputs[0] ) );
+      }
+#endif
+
+      /* run shader */
+      tgsi_exec_machine_run( &machine );
+
+      /* store result color */
+      memcpy(quad->outputs.color,
+             &aoutputs[FRAG_ATTRIB_COL0].xyzw[0].f[0],
+             sizeof(quad->outputs.color));
+      if (softpipe->need_z) {
+         /* XXX temporary */
+         quad->outputs.depth[0] = exec.attr[0][2][0];
+         quad->outputs.depth[1] = exec.attr[0][2][1];
+         quad->outputs.depth[2] = exec.attr[0][2][2];
+         quad->outputs.depth[3] = exec.attr[0][2][3];
+      }
+   }
+#else
+   {
+      GLuint attr = softpipe->fp_attr_to_slot[FRAG_ATTRIB_COL0];
+      assert(attr);
+
+      memcpy(quad->outputs.color, 
+            exec.attr[attr], 
+            sizeof(quad->outputs.color));
+
+      if (softpipe->need_z) {
+         quad->outputs.depth[0] = exec.attr[0][2][0];
+         quad->outputs.depth[1] = exec.attr[0][2][1];
+         quad->outputs.depth[2] = exec.attr[0][2][2];
+         quad->outputs.depth[3] = exec.attr[0][2][3];
+      }
+   }
+#endif
+
+   /* shader may cull fragments */
+   if (quad->mask)
+      qs->next->run(qs->next, quad);
+}
+
+
+
+struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = shade_quad;
+
+   return stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_quad_occlusion.c b/src/mesa/pipe/softpipe/sp_quad_occlusion.c
new file mode 100644 (file)
index 0000000..843c462
--- /dev/null
@@ -0,0 +1,67 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+
+/**
+ * \brief  Quad occlusion counter stage
+ * \author  Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "pipe/p_defines.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_surface.h"
+#include "sp_quad.h"
+
+
+static void
+occlusion_count_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+
+   softpipe->occlusion_counter += (quad->mask     ) & 1;
+   softpipe->occlusion_counter += (quad->mask >> 1) & 1;
+   softpipe->occlusion_counter += (quad->mask >> 2) & 1;
+   softpipe->occlusion_counter += (quad->mask >> 3) & 1;
+
+   if (quad->mask)
+      qs->next->run(qs->next, quad);
+}
+
+
+struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = occlusion_count_quad;
+
+   return stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_quad_output.c b/src/mesa/pipe/softpipe/sp_quad_output.c
new file mode 100644 (file)
index 0000000..12ab1ec
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * 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.
+ */
+
+/* Vertices are just an array of floats, with all the attributes
+ * packed.  We currently assume a layout like:
+ *
+ * attr[0][0..3] - window position
+ * attr[1..n][0..3] - remaining attributes.
+ *
+ * Attributes are assumed to be 4 floats wide but are packed so that
+ * all the enabled attributes run contiguously.
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_surface.h"
+#include "sp_quad.h"
+
+
+static void mask_copy( GLfloat (*dest)[4],
+                      GLfloat (*src)[4],
+                      GLuint mask )
+{
+   GLuint i, j;
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+        for (j = 0; j < 4; j++) {
+           dest[j][i] = src[j][i];
+        }
+      }
+   }
+}
+
+
+/**
+ * Write quad to framebuffer, taking mask into account.
+ *
+ * Note that surfaces support only full quad reads and writes.
+ */
+static void
+output_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+   struct softpipe_surface *sps = softpipe_surface(softpipe->cbuf);
+
+   if (quad->mask != MASK_ALL) {
+      GLfloat tmp[4][QUAD_SIZE];
+
+      /* XXX probably add a masked-write function someday */
+
+      sps->read_quad_f_swz(sps, quad->x0, quad->y0, tmp);
+
+      mask_copy( tmp, quad->outputs.color, quad->mask );
+
+      sps->write_quad_f_swz(sps, quad->x0, quad->y0, tmp);
+   }
+   else if (quad->mask) {
+      sps->write_quad_f_swz(sps, quad->x0, quad->y0, quad->outputs.color);
+   }
+}
+
+
+struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = output_quad;
+
+   return stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_quad_stencil.c b/src/mesa/pipe/softpipe/sp_quad_stencil.c
new file mode 100644 (file)
index 0000000..0b37474
--- /dev/null
@@ -0,0 +1,288 @@
+
+/**
+ * \brief Quad stencil testing
+ */
+
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_surface.h"
+#include "sp_quad.h"
+#include "pipe/p_defines.h"
+
+
+/** Only 8-bit stencil supported */
+#define STENCIL_MAX 0xff
+
+
+/**
+ * Do the basic stencil test (compare stencil buffer values against the
+ * reference value.
+ *
+ * \param stencilVals  the stencil values from the stencil buffer
+ * \param func  the stencil func (PIPE_FUNC_x)
+ * \param ref  the stencil reference value
+ * \param valMask  the stencil value mask indicating which bits of the stencil
+ *                 values and ref value are to be used.
+ * \return mask indicating which pixels passed the stencil test
+ */
+static GLbitfield
+do_stencil_test(const GLubyte stencilVals[QUAD_SIZE], GLuint func,
+                GLbitfield ref, GLbitfield valMask)
+{
+   GLbitfield passMask = 0x0;
+   GLuint j;
+
+   ref &= valMask;
+
+   switch (func) {
+   case PIPE_FUNC_NEVER:
+      /* passMask = 0x0 */
+      break;
+   case PIPE_FUNC_LESS:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if ((stencilVals[j] & valMask) < ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_EQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if ((stencilVals[j] & valMask) == ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_LEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if ((stencilVals[j] & valMask) <= ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_GREATER:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if ((stencilVals[j] & valMask) > ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_NOTEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if ((stencilVals[j] & valMask) != ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_GEQUAL:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if ((stencilVals[j] & valMask) >= ref) {
+            passMask |= (1 << j);
+         }
+      }
+      break;
+   case PIPE_FUNC_ALWAYS:
+      passMask = MASK_ALL;
+      break;
+   default:
+      assert(0);
+   }
+
+   return passMask;
+}
+
+
+/**
+ * Apply the stencil operator to stencil values.
+ *
+ * \param stencilVals  the stencil buffer values (read and written)
+ * \param mask  indicates which pixels to update
+ * \param op  the stencil operator (PIPE_STENCIL_OP_x)
+ * \param ref  the stencil reference value
+ * \param wrtMask  writemask controlling which bits are changed in the
+ *                 stencil values
+ */
+static void
+apply_stencil_op(GLubyte stencilVals[QUAD_SIZE],
+                 GLbitfield mask, GLuint op, GLubyte ref, GLubyte wrtMask)
+{
+   GLuint j;
+   GLubyte newstencil[QUAD_SIZE];
+
+   for (j = 0; j < QUAD_SIZE; j++) {
+      newstencil[j] = stencilVals[j];
+   }
+
+   switch (op) {
+   case PIPE_STENCIL_OP_KEEP:
+      /* no-op */
+      break;
+   case PIPE_STENCIL_OP_ZERO:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (mask & (1 << j)) {
+            newstencil[j] = 0;
+         }
+      }
+      break;
+   case PIPE_STENCIL_OP_REPLACE:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (mask & (1 << j)) {
+            newstencil[j] = ref;
+         }
+      }
+      break;
+   case PIPE_STENCIL_OP_INCR:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (mask & (1 << j)) {
+            if (stencilVals[j] < STENCIL_MAX) {
+               newstencil[j] = stencilVals[j] + 1;
+            }
+         }
+      }
+      break;
+   case PIPE_STENCIL_OP_DECR:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (mask & (1 << j)) {
+            if (stencilVals[j] > 0) {
+               newstencil[j] = stencilVals[j] - 1;
+            }
+         }
+      }
+      break;
+   case PIPE_STENCIL_OP_INCR_WRAP:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (mask & (1 << j)) {
+            newstencil[j] = stencilVals[j] + 1;
+         }
+      }
+      break;
+   case PIPE_STENCIL_OP_DECR_WRAP:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (mask & (1 << j)) {
+            newstencil[j] = stencilVals[j] - 1;
+         }
+      }
+      break;
+   case PIPE_STENCIL_OP_INVERT:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (mask & (1 << j)) {
+            newstencil[j] = ~stencilVals[j];
+         }
+      }
+      break;
+   default:
+      assert(0);
+   }
+
+   /*
+    * update the stencil values
+    */
+   if (wrtMask != STENCIL_MAX) {
+      /* apply bit-wise stencil buffer writemask */
+      for (j = 0; j < QUAD_SIZE; j++) {
+         stencilVals[j] = (wrtMask & newstencil[j]) | (~wrtMask & stencilVals[j]);
+      }
+   }
+   else {
+      for (j = 0; j < QUAD_SIZE; j++) {
+         stencilVals[j] = newstencil[j];
+      }
+   }
+}
+
+
+/**
+ * Do stencil (and depth) testing.  Stenciling depends on the outcome of
+ * depth testing.
+ */
+static void
+stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+   struct softpipe_surface *s_surf = softpipe_surface(softpipe->framebuffer.sbuf);
+   GLuint func, zFailOp, zPassOp, failOp;
+   GLubyte ref, wrtMask, valMask;
+   GLubyte stencilVals[QUAD_SIZE];
+
+   /* choose front or back face function, operator, etc */
+   /* XXX we could do these initializations once per primitive */
+   if (softpipe->stencil.back_enabled && quad->facing) {
+      func = softpipe->stencil.back_func;
+      failOp = softpipe->stencil.back_fail_op;
+      zFailOp = softpipe->stencil.back_zfail_op;
+      zPassOp = softpipe->stencil.back_zpass_op;
+      ref = softpipe->stencil.ref_value[1];
+      wrtMask = softpipe->stencil.write_mask[1];
+      valMask = softpipe->stencil.value_mask[1];
+   }
+   else {
+      func = softpipe->stencil.front_func;
+      failOp = softpipe->stencil.front_fail_op;
+      zFailOp = softpipe->stencil.front_zfail_op;
+      zPassOp = softpipe->stencil.front_zpass_op;
+      ref = softpipe->stencil.ref_value[0];
+      wrtMask = softpipe->stencil.write_mask[0];
+      valMask = softpipe->stencil.value_mask[0];
+   }
+
+   assert(s_surf); /* shouldn't get here if there's no stencil buffer */
+   s_surf->read_quad_stencil(s_surf, quad->x0, quad->y0, stencilVals);
+
+   /* do the stencil test first */
+   {
+      GLbitfield passMask, failMask;
+      passMask = do_stencil_test(stencilVals, func, ref, valMask);
+      failMask = quad->mask & ~passMask;
+      quad->mask &= passMask;
+
+      if (failOp != PIPE_STENCIL_OP_KEEP) {
+         apply_stencil_op(stencilVals, failMask, failOp, ref, wrtMask);
+      }
+   }
+
+   if (quad->mask) {
+
+      /* now the pixels that passed the stencil test are depth tested */
+      if (softpipe->depth_test.enabled) {
+         const GLbitfield origMask = quad->mask;
+
+         sp_depth_test_quad(qs, quad);  /* quad->mask is updated */
+
+         /* update stencil buffer values according to z pass/fail result */
+         if (zFailOp != PIPE_STENCIL_OP_KEEP) {
+            const GLbitfield failMask = origMask & ~quad->mask;
+            apply_stencil_op(stencilVals, failMask, zFailOp, ref, wrtMask);
+         }
+
+         if (zPassOp != PIPE_STENCIL_OP_KEEP) {
+            const GLbitfield passMask = origMask & quad->mask;
+            apply_stencil_op(stencilVals, passMask, zPassOp, ref, wrtMask);
+         }
+      }
+      else {
+         /* no depth test, apply Zpass operator to stencil buffer values */
+         apply_stencil_op(stencilVals, quad->mask, zPassOp, ref, wrtMask);
+      }
+
+   }
+
+   s_surf->write_quad_stencil(s_surf, quad->x0, quad->y0, stencilVals);
+
+   if (quad->mask)
+      qs->next->run(qs->next, quad);
+}
+
+
+
+
+struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = stencil_test_quad;
+
+   return stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_quad_stipple.c b/src/mesa/pipe/softpipe/sp_quad_stipple.c
new file mode 100644 (file)
index 0000000..cad1a14
--- /dev/null
@@ -0,0 +1,48 @@
+
+/**
+ * quad polygon stipple stage
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_quad.h"
+#include "pipe/p_defines.h"
+
+
+/**
+ * Apply polygon stipple to quads produced by triangle rasterization
+ */
+static void
+stipple_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+   if (quad->prim == PRIM_TRI) {
+      struct softpipe_context *softpipe = qs->softpipe;
+      const GLint col0 = quad->x0 % 32;
+      const GLint row0 = quad->y0 % 32;
+      const GLuint stipple0 = softpipe->poly_stipple.stipple[row0];
+      const GLuint stipple1 = softpipe->poly_stipple.stipple[row0 + 1];
+
+      /* XXX there may be a better way to lay out the stored stipple
+       * values to further simplify this computation.
+       */
+      quad->mask &= (((stipple0 >> col0) & 0x3) | 
+                     (((stipple1 >> col0) & 0x3) << 2));
+
+      if (quad->mask)
+         qs->next->run(qs->next, quad);
+   }
+}
+
+
+struct quad_stage *
+sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe )
+{
+   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
+
+   stage->softpipe = softpipe;
+   stage->run = stipple_quad;
+
+   return stage;
+}
diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h
new file mode 100644 (file)
index 0000000..71c1a2d
--- /dev/null
@@ -0,0 +1,87 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef SP_STATE_H
+#define SP_STATE_H
+
+#include "glheader.h"
+#include "pipe/p_state.h"
+
+
+void softpipe_set_framebuffer_state( struct pipe_context *,
+                            const struct pipe_framebuffer_state * );
+
+void softpipe_set_alpha_test_state( struct pipe_context *,
+                                    const struct pipe_alpha_test_state * );
+
+void softpipe_set_blend_state( struct pipe_context *,
+                               const struct pipe_blend_state * );
+
+void softpipe_set_blend_color( struct pipe_context *pipe,
+                               const struct pipe_blend_color *blend_color );
+
+void softpipe_set_clear_color_state( struct pipe_context *,
+                                     const struct pipe_clear_color_state * );
+
+void softpipe_set_clip_state( struct pipe_context *,
+                            const struct pipe_clip_state * );
+
+void softpipe_set_depth_test_state( struct pipe_context *,
+                                    const struct pipe_depth_state * );
+
+void softpipe_set_fs_state( struct pipe_context *,
+                          const struct pipe_fs_state * );
+
+void softpipe_set_polygon_stipple( struct pipe_context *,
+                                 const struct pipe_poly_stipple * );
+
+void softpipe_set_scissor_state( struct pipe_context *,
+                                 const struct pipe_scissor_state * );
+
+void softpipe_set_setup_state( struct pipe_context *,
+                             const struct pipe_setup_state * );
+
+void softpipe_set_sampler_state( struct pipe_context *,
+                                 GLuint unit,
+                                 const struct pipe_sampler_state * );
+
+void softpipe_set_stencil_state( struct pipe_context *,
+                                 const struct pipe_stencil_state * );
+
+void softpipe_set_texture_state( struct pipe_context *,
+                                 GLuint unit,
+                                 struct pipe_texture_object * );
+
+void softpipe_set_viewport_state( struct pipe_context *,
+                                  const struct pipe_viewport_state * );
+
+void softpipe_update_derived( struct softpipe_context *softpipe );
+
+#endif
diff --git a/src/mesa/pipe/softpipe/sp_state_blend.c b/src/mesa/pipe/softpipe/sp_state_blend.c
new file mode 100644 (file)
index 0000000..8bc22b0
--- /dev/null
@@ -0,0 +1,93 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+#include "imports.h"
+
+#include "sp_context.h"
+#include "sp_state.h"
+
+
+void softpipe_set_blend_state( struct pipe_context *pipe,
+                            const struct pipe_blend_state *blend )
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->blend = *blend;
+
+   softpipe->dirty |= SP_NEW_BLEND;
+}
+
+
+void softpipe_set_blend_color( struct pipe_context *pipe,
+                            const struct pipe_blend_color *blend_color )
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->blend_color = *blend_color;
+
+   softpipe->dirty |= SP_NEW_BLEND;
+}
+
+
+/** XXX move someday?  Or consolidate all these simple state setters
+ * into one file.
+ */
+void
+softpipe_set_depth_test_state(struct pipe_context *pipe,
+                              const struct pipe_depth_state *depth)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->depth_test = *depth;
+
+   softpipe->dirty |= SP_NEW_DEPTH_TEST;
+}
+
+void
+softpipe_set_alpha_test_state(struct pipe_context *pipe,
+                              const struct pipe_alpha_test_state *alpha)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->alpha_test = *alpha;
+
+   softpipe->dirty |= SP_NEW_ALPHA_TEST;
+}
+
+void
+softpipe_set_stencil_state(struct pipe_context *pipe,
+                           const struct pipe_stencil_state *stencil)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->stencil = *stencil;
+
+   softpipe->dirty |= SP_NEW_STENCIL;
+}
+
diff --git a/src/mesa/pipe/softpipe/sp_state_clip.c b/src/mesa/pipe/softpipe/sp_state_clip.c
new file mode 100644 (file)
index 0000000..8cf4383
--- /dev/null
@@ -0,0 +1,85 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+#include "imports.h"
+
+#include "sp_context.h"
+#include "sp_state.h"
+#include "pipe/draw/draw_context.h"
+
+
+void softpipe_set_clip_state( struct pipe_context *pipe,
+                            const struct pipe_clip_state *clip )
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   /* pass the clip state to the draw module */
+   draw_set_clip_state(softpipe->draw, clip);
+}
+
+
+
+/* Called when driver state tracker notices changes to the viewport
+ * matrix:
+ */
+void softpipe_set_viewport_state( struct pipe_context *pipe,
+                                  const struct pipe_viewport_state *viewport )
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->viewport = *viewport; /* struct copy */
+   softpipe->dirty |= SP_NEW_VIEWPORT;
+
+   /* pass the viewport info to the draw module */
+   draw_set_viewport_state(softpipe->draw, viewport);
+
+   /* Using tnl/ and vf/ modules is temporary while getting started.
+    * Full pipe will have vertex shader, vertex fetch of its own.
+    */
+}
+
+
+void softpipe_set_scissor_state( struct pipe_context *pipe,
+                                 const struct pipe_scissor_state *scissor )
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   memcpy( &softpipe->scissor, scissor, sizeof(*scissor) );
+   softpipe->dirty |= SP_NEW_SCISSOR;
+}
+
+
+void softpipe_set_polygon_stipple( struct pipe_context *pipe,
+                                   const struct pipe_poly_stipple *stipple )
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   memcpy( &softpipe->poly_stipple, stipple, sizeof(*stipple) );
+   softpipe->dirty |= SP_NEW_STIPPLE;
+}
diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c
new file mode 100644 (file)
index 0000000..e1faaed
--- /dev/null
@@ -0,0 +1,224 @@
+/**************************************************************************
+ * 
+ * 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 "main/glheader.h"
+#include "main/macros.h"
+#include "main/enums.h"
+
+#include "vf/vf.h"
+#include "pipe/draw/draw_context.h"
+#include "sp_context.h"
+#include "sp_state.h"
+
+
+#define EMIT_ATTR( VF_ATTR, FRAG_ATTR, INTERP )                        \
+do {                                                           \
+   slot_to_vf_attr[softpipe->nr_attrs] = VF_ATTR;              \
+   softpipe->vf_attr_to_slot[VF_ATTR] = softpipe->nr_attrs;    \
+   softpipe->fp_attr_to_slot[FRAG_ATTR] = softpipe->nr_attrs;  \
+   softpipe->interp[softpipe->nr_attrs] = INTERP;              \
+   softpipe->nr_attrs++;                                       \
+   attr_mask |= (1 << (VF_ATTR));                              \
+} while (0)
+
+
+static const GLuint frag_to_vf[FRAG_ATTRIB_MAX] = 
+{
+   VF_ATTRIB_POS,
+   VF_ATTRIB_COLOR0,
+   VF_ATTRIB_COLOR1,
+   VF_ATTRIB_FOG,
+   VF_ATTRIB_TEX0,
+   VF_ATTRIB_TEX1,
+   VF_ATTRIB_TEX2,
+   VF_ATTRIB_TEX3,
+   VF_ATTRIB_TEX4,
+   VF_ATTRIB_TEX5,
+   VF_ATTRIB_TEX6,
+   VF_ATTRIB_TEX7,
+   VF_ATTRIB_VAR0,
+   VF_ATTRIB_VAR1,
+   VF_ATTRIB_VAR2,
+   VF_ATTRIB_VAR3,
+   VF_ATTRIB_VAR4,
+   VF_ATTRIB_VAR5,
+   VF_ATTRIB_VAR6,
+   VF_ATTRIB_VAR7,
+};
+
+
+/**
+ * Determine which post-transform / pre-rasterization vertex attributes
+ * we need.
+ * Derived from:  fs, setup states.
+ */
+static void calculate_vertex_layout( struct softpipe_context *softpipe )
+{
+   const GLbitfield inputsRead = softpipe->fs.inputs_read;
+   GLuint slot_to_vf_attr[VF_ATTRIB_MAX];
+   GLbitfield attr_mask = 0x0;
+   GLuint i;
+
+   /* Need Z if depth test is enabled or the fragment program uses the
+    * fragment position (XYZW).
+    */
+   if (softpipe->depth_test.enabled ||
+       (inputsRead & FRAG_ATTRIB_WPOS))
+      softpipe->need_z = GL_TRUE;
+   else
+      softpipe->need_z = GL_FALSE;
+
+   /* Need W if we do any perspective-corrected interpolation or the
+    * fragment program uses the fragment position.
+    */
+   if (inputsRead & FRAG_ATTRIB_WPOS)
+      softpipe->need_w = GL_TRUE;
+   else
+      softpipe->need_w = GL_FALSE;
+
+
+   softpipe->nr_attrs = 0;
+   memset(slot_to_vf_attr, 0, sizeof(slot_to_vf_attr));
+
+   memset(softpipe->fp_attr_to_slot, 0, sizeof(softpipe->fp_attr_to_slot));
+   memset(softpipe->vf_attr_to_slot, 0, sizeof(softpipe->vf_attr_to_slot));
+
+   /* TODO - Figure out if we need to do perspective divide, etc.
+    */
+   EMIT_ATTR(VF_ATTRIB_POS, FRAG_ATTRIB_WPOS, INTERP_LINEAR);
+      
+   /* Pull in the rest of the attributes.  They are all in float4
+    * format.  Future optimizations could be to keep some attributes
+    * as fixed point or ubyte format.
+    */
+   for (i = 1; i < FRAG_ATTRIB_TEX0; i++) {
+      if (inputsRead & (1 << i)) {
+         assert(i < sizeof(frag_to_vf) / sizeof(frag_to_vf[0]));
+         if (softpipe->setup.flatshade
+             && (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1))
+            EMIT_ATTR(frag_to_vf[i], i, INTERP_CONSTANT);
+         else
+            EMIT_ATTR(frag_to_vf[i], i, INTERP_LINEAR);
+      }
+   }
+
+   for (i = FRAG_ATTRIB_TEX0; i < FRAG_ATTRIB_MAX; i++) {
+      if (inputsRead & (1 << i)) {
+         assert(i < sizeof(frag_to_vf) / sizeof(frag_to_vf[0]));
+         EMIT_ATTR(frag_to_vf[i], i, INTERP_PERSPECTIVE);
+         softpipe->need_w = GL_TRUE;
+      }
+   }
+
+   softpipe->nr_frag_attrs = softpipe->nr_attrs;
+
+   /* Additional attributes required for setup: Just twosided
+    * lighting.  Edgeflag is dealt with specially by setting bits in
+    * the vertex header.
+    */
+   if (softpipe->setup.light_twoside) {
+      if (inputsRead & FRAG_BIT_COL0) {
+        EMIT_ATTR(VF_ATTRIB_BFC0, FRAG_ATTRIB_MAX, 0); /* XXX: mark as discarded after setup */
+      }
+           
+      if (inputsRead & FRAG_BIT_COL1) {
+        EMIT_ATTR(VF_ATTRIB_BFC1, FRAG_ATTRIB_MAX, 0); /* XXX: discard after setup */
+      }
+   }
+
+   /* If the attributes have changed, tell the draw module (which in turn
+    * tells the vf module) about the new vertex layout.
+    */
+   if (attr_mask != softpipe->attr_mask) {
+      softpipe->attr_mask = attr_mask;
+
+      draw_set_vertex_attributes( softpipe->draw,
+                                 slot_to_vf_attr,
+                                 softpipe->nr_attrs );
+   }
+}
+
+
+/**
+ * Recompute cliprect from scissor bounds, scissor enable and surface size.
+ */
+static void
+compute_cliprect(struct softpipe_context *sp)
+{
+   GLint surfWidth, surfHeight;
+
+   if (sp->framebuffer.num_cbufs > 0) {
+      surfWidth = sp->framebuffer.cbufs[0]->width;
+      surfHeight = sp->framebuffer.cbufs[0]->height;
+   }
+   else {
+      /* no surface? */
+      surfWidth = sp->scissor.maxx;
+      surfHeight = sp->scissor.maxy;
+   }
+
+   if (sp->setup.scissor) {
+      /* clip to scissor rect */
+      sp->cliprect.minx = MAX2(sp->scissor.minx, 0);
+      sp->cliprect.miny = MAX2(sp->scissor.miny, 0);
+      sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth);
+      sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight);
+   }
+   else {
+      /* clip to surface bounds */
+      sp->cliprect.minx = 0;
+      sp->cliprect.miny = 0;
+      sp->cliprect.maxx = surfWidth;
+      sp->cliprect.maxy = surfHeight;
+   }
+}
+
+
+/* Hopefully this will remain quite simple, otherwise need to pull in
+ * something like the state tracker mechanism.
+ */
+void softpipe_update_derived( struct softpipe_context *softpipe )
+{
+   if (softpipe->dirty & (SP_NEW_SETUP | SP_NEW_FS))
+      calculate_vertex_layout( softpipe );
+
+   if (softpipe->dirty & (SP_NEW_SCISSOR |
+                          SP_NEW_STENCIL |
+                          SP_NEW_FRAMEBUFFER))
+      compute_cliprect(softpipe);
+
+   if (softpipe->dirty & (SP_NEW_BLEND |
+                          SP_NEW_DEPTH_TEST |
+                          SP_NEW_ALPHA_TEST |
+                          SP_NEW_FRAMEBUFFER |
+                          SP_NEW_STENCIL |
+                          SP_NEW_SETUP |
+                          SP_NEW_FS))
+      sp_build_quad_pipeline(softpipe);
+
+   softpipe->dirty = 0;
+}
diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c
new file mode 100644 (file)
index 0000000..c7ef1f1
--- /dev/null
@@ -0,0 +1,50 @@
+/**************************************************************************
+ * 
+ * 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 "sp_context.h"
+#include "sp_state.h"
+
+
+
+void softpipe_set_fs_state( struct pipe_context *pipe,
+                          const struct pipe_fs_state *fs )
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   memcpy(&softpipe->fs, fs, sizeof(*fs));
+
+   softpipe->dirty |= SP_NEW_FS;
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c
new file mode 100644 (file)
index 0000000..9ef71f7
--- /dev/null
@@ -0,0 +1,64 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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:
+ *  Brian Paul
+ */
+
+#include "imports.h"
+
+#include "sp_context.h"
+#include "sp_state.h"
+
+
+
+void
+softpipe_set_sampler_state(struct pipe_context *pipe,
+                           GLuint unit,
+                           const struct pipe_sampler_state *sampler)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   assert(unit < PIPE_MAX_SAMPLERS);
+   softpipe->sampler[unit] = *sampler;
+
+   softpipe->dirty |= SP_NEW_SAMPLER;
+}
+
+
+void
+softpipe_set_texture_state(struct pipe_context *pipe,
+                           GLuint unit,
+                           struct pipe_texture_object *texture)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   assert(unit < PIPE_MAX_SAMPLERS);
+   softpipe->texture[unit] = texture;  /* ptr, not struct */
+
+   softpipe->dirty |= SP_NEW_TEXTURE;
+}
diff --git a/src/mesa/pipe/softpipe/sp_state_setup.c b/src/mesa/pipe/softpipe/sp_state_setup.c
new file mode 100644 (file)
index 0000000..4715a26
--- /dev/null
@@ -0,0 +1,47 @@
+/**************************************************************************
+ * 
+ * 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 "pipe/p_defines.h"
+#include "sp_context.h"
+#include "sp_state.h"
+#include "pipe/draw/draw_context.h"
+
+
+void softpipe_set_setup_state( struct pipe_context *pipe,
+                             const struct pipe_setup_state *setup )
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   /* pass-through to draw module */
+   draw_set_setup_state(softpipe->draw, setup);
+
+   memcpy( &softpipe->setup, setup, sizeof(*setup) );
+
+   softpipe->dirty |= SP_NEW_SETUP;
+}
+
+
diff --git a/src/mesa/pipe/softpipe/sp_state_surface.c b/src/mesa/pipe/softpipe/sp_state_surface.c
new file mode 100644 (file)
index 0000000..8ce81eb
--- /dev/null
@@ -0,0 +1,61 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+#include "imports.h"
+
+#include "sp_context.h"
+#include "sp_state.h"
+#include "sp_surface.h"
+
+
+/*
+ * XXX this might get moved someday
+ */
+void
+softpipe_set_framebuffer_state(struct pipe_context *pipe,
+                               const struct pipe_framebuffer_state *fb)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->framebuffer = *fb; /* struct copy */
+
+   softpipe->dirty |= SP_NEW_FRAMEBUFFER;
+}
+
+
+
+
+void
+softpipe_set_clear_color_state(struct pipe_context *pipe,
+                               const struct pipe_clear_color_state *clear)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->clear_color = *clear; /* struct copy */
+}
diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c
new file mode 100644 (file)
index 0000000..16bbacb
--- /dev/null
@@ -0,0 +1,153 @@
+/**************************************************************************
+ * 
+ * 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 "sp_context.h"
+#include "sp_state.h"
+#include "sp_surface.h"
+#include "sp_headers.h"
+
+static void rgba8_read_quad_f( struct softpipe_surface *gs,
+                              GLint x, GLint y,
+                              GLfloat (*rgba)[NUM_CHANNELS] )
+{
+   GLuint i, j, k = 0;
+
+   for (i = 0; i < 2; i++) {
+      for (j = 0; j < 2; j++, k++) {
+        GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
+        rgba[k][0] = ptr[0] * (1.0 / 255.0);
+        rgba[k][1] = ptr[1] * (1.0 / 255.0);
+        rgba[k][2] = ptr[2] * (1.0 / 255.0);
+        rgba[k][3] = ptr[3] * (1.0 / 255.0);
+      }
+   }
+}
+
+static void rgba8_read_quad_f_swz( struct softpipe_surface *gs,
+                                  GLint x, GLint y,
+                                  GLfloat (*rrrr)[QUAD_SIZE] )
+{
+   GLuint i, j, k = 0;
+
+   for (i = 0; i < 2; i++) {
+      for (j = 0; j < 2; j++, k++) {
+        GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
+        rrrr[0][k] = ptr[0] * (1.0 / 255.0);
+        rrrr[1][k] = ptr[1] * (1.0 / 255.0);
+        rrrr[2][k] = ptr[2] * (1.0 / 255.0);
+        rrrr[3][k] = ptr[3] * (1.0 / 255.0);
+      }
+   }
+}
+
+static void rgba8_write_quad_f( struct softpipe_surface *gs,
+                               GLint x, GLint y,
+                               GLfloat (*rgba)[NUM_CHANNELS] )
+{
+   GLuint i, j, k = 0;
+
+   for (i = 0; i < 2; i++) {
+      for (j = 0; j < 2; j++, k++) {
+        GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
+        ptr[0] = rgba[k][0] * 255.0;
+        ptr[1] = rgba[k][1] * 255.0;
+        ptr[2] = rgba[k][2] * 255.0;
+        ptr[3] = rgba[k][3] * 255.0;
+      }
+   }
+}
+
+static void rgba8_write_quad_f_swz( struct softpipe_surface *gs,
+                                   GLint x, GLint y,
+                                   GLfloat (*rrrr)[QUAD_SIZE] )
+{
+   GLuint i, j, k = 0;
+
+   for (i = 0; i < 2; i++) {
+      for (j = 0; j < 2; j++, k++) {
+        GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
+        ptr[0] = rrrr[0][k] * 255.0;
+        ptr[1] = rrrr[1][k] * 255.0;
+        ptr[2] = rrrr[2][k] * 255.0;
+        ptr[3] = rrrr[3][k] * 255.0;
+      }
+   }
+}
+
+
+
+
+static void rgba8_read_quad_ub( struct softpipe_surface *gs,
+                               GLint x, GLint y,
+                               GLubyte (*rgba)[NUM_CHANNELS] )
+{
+   GLuint i, j, k = 0;
+
+   for (i = 0; i < 2; i++) {
+      for (j = 0; j < 2; j++, k++) {
+        GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
+        rgba[k][0] = ptr[0];
+        rgba[k][1] = ptr[1];
+        rgba[k][2] = ptr[2];
+        rgba[k][3] = ptr[3];
+      }
+   }
+}
+
+
+static void rgba8_write_quad_ub( struct softpipe_surface *gs,
+                                GLint x, GLint y,
+                                GLubyte (*rgba)[NUM_CHANNELS] )
+{
+   GLuint i, j, k = 0;
+
+   for (i = 0; i < 2; i++) {
+      for (j = 0; j < 2; j++, k++) {
+        GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
+        ptr[0] = rgba[k][0];
+        ptr[1] = rgba[k][1];
+        ptr[2] = rgba[k][2];
+        ptr[3] = rgba[k][3];
+      }
+   }
+}
+
+
+
+
+struct softpipe_surface_type gs_rgba8 = {
+   G_SURFACE_RGBA_8888,
+   rgba8_read_quad_f,
+   rgba8_read_quad_f_swz,
+   rgba8_read_quad_ub,
+   rgba8_write_quad_f,
+   rgba8_write_quad_f_swz,
+   rgba8_write_quad_ub,
+};
+
+
+
diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h
new file mode 100644 (file)
index 0000000..3ba732c
--- /dev/null
@@ -0,0 +1,101 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef SP_SURFACE_H
+#define SP_SURFACE_H
+
+#include "glheader.h"
+#include "sp_headers.h"
+
+struct softpipe_surface;
+
+#define G_SURFACE_RGBA_8888  0x1
+
+
+/**
+ * Softpipe surface is derived from pipe_surface.
+ */
+struct softpipe_surface {
+   struct pipe_surface surface;
+
+   /**
+    * Functions for read/writing surface data
+    */
+   void (*read_quad_f)( struct softpipe_surface *,
+                       GLint x, GLint y,
+                       GLfloat (*rgba)[NUM_CHANNELS] );
+
+   void (*read_quad_f_swz)( struct softpipe_surface *,
+                           GLint x, GLint y,
+                           GLfloat (*rrrr)[QUAD_SIZE] );
+
+   void (*read_quad_ub)( struct softpipe_surface *,
+                        GLint x, GLint y,
+                        GLubyte (*rgba)[NUM_CHANNELS] );
+
+
+   void (*write_quad_f)( struct softpipe_surface *,
+                        GLint x, GLint y,
+                        GLfloat (*rgba)[NUM_CHANNELS] );
+
+   void (*write_quad_f_swz)( struct softpipe_surface *,
+                            GLint x, GLint y,
+                            GLfloat (*rrrr)[QUAD_SIZE] );
+
+
+   void (*write_quad_ub)( struct softpipe_surface *,
+                         GLint x, GLint y,
+                         GLubyte (*rgba)[NUM_CHANNELS] );
+
+   void (*write_mono_row_ub)( struct softpipe_surface *,
+                              GLuint count, GLint x, GLint y,
+                              GLubyte rgba[NUM_CHANNELS] );
+
+   void (*read_quad_z)(struct softpipe_surface *,
+                       GLint x, GLint y, GLuint zzzz[QUAD_SIZE]);
+   void (*write_quad_z)(struct softpipe_surface *,
+                        GLint x, GLint y, const GLuint zzzz[QUAD_SIZE]);
+
+   void (*read_quad_stencil)(struct softpipe_surface *,
+                             GLint x, GLint y, GLubyte ssss[QUAD_SIZE]);
+   void (*write_quad_stencil)(struct softpipe_surface *,
+                              GLint x, GLint y, const GLubyte ssss[QUAD_SIZE]);
+};
+
+
+/** Cast wrapper */
+static INLINE struct softpipe_surface *
+softpipe_surface(struct pipe_surface *ps)
+{
+   return (struct softpipe_surface *) ps;
+}
+
+
+#endif /* SP_SURFACE_H */
diff --git a/src/mesa/pipe/softpipe/sp_z_surface.c b/src/mesa/pipe/softpipe/sp_z_surface.c
new file mode 100644 (file)
index 0000000..744737c
--- /dev/null
@@ -0,0 +1,241 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+
+/**
+ * Software Z buffer/surface.
+ *
+ * \author Brian Paul
+ */
+
+
+#include "main/imports.h"
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "sp_context.h"
+#include "sp_surface.h"
+#include "sp_z_surface.h"
+
+static void*
+z_map(struct pipe_buffer *pb, GLuint access_mode)
+{
+   struct softpipe_surface *sps = (struct softpipe_surface *) pb;
+   sps->surface.ptr = pb->ptr;
+   sps->surface.stride = sps->surface.width;
+   return pb->ptr;
+}
+
+static void
+z_unmap(struct pipe_buffer *pb)
+{
+   struct softpipe_surface *sps = (struct softpipe_surface *) pb;
+   sps->surface.ptr = NULL;
+   sps->surface.stride = 0;
+}
+
+static void
+z_resize(struct pipe_surface *ps, GLuint width, GLuint height)
+{
+   struct softpipe_surface *sps = (struct softpipe_surface *) ps;
+
+   if (sps->surface.buffer.ptr)
+      free(sps->surface.buffer.ptr);
+
+   sps->surface.stride = sps->surface.width;
+   if (sps->surface.format == PIPE_FORMAT_U_Z16)
+      sps->surface.cpp = 2;
+   else if (sps->surface.format == PIPE_FORMAT_U_Z32 ||
+            sps->surface.format == PIPE_FORMAT_Z24_S8)
+      sps->surface.cpp = 4;
+   else
+      assert(0);
+
+   ps->buffer.ptr = (GLubyte *) malloc(width * height * sps->surface.cpp);
+   ps->width = width;
+   ps->height = height;
+
+}
+
+static void
+z16_read_quad_z(struct softpipe_surface *sps,
+                GLint x, GLint y, GLuint zzzz[QUAD_SIZE])
+{
+   const GLushort *src
+      = (GLushort *) sps->surface.ptr + y * sps->surface.stride + x;
+
+   assert(sps->surface.format == PIPE_FORMAT_U_Z16);
+
+   /* converting GLushort to GLuint: */
+   zzzz[0] = src[0];
+   zzzz[1] = src[1];
+   zzzz[2] = src[sps->surface.width + 0];
+   zzzz[3] = src[sps->surface.width + 1];
+}
+
+static void
+z16_write_quad_z(struct softpipe_surface *sps,
+                 GLint x, GLint y, const GLuint zzzz[QUAD_SIZE])
+{
+   GLushort *dst = (GLushort *) sps->surface.ptr + y * sps->surface.stride + x;
+
+   assert(sps->surface.format == PIPE_FORMAT_U_Z16);
+
+   /* converting GLuint to GLushort: */
+   dst[0] = zzzz[0];
+   dst[1] = zzzz[1];
+   dst[sps->surface.width + 0] = zzzz[2];
+   dst[sps->surface.width + 1] = zzzz[3];
+}
+
+static void
+z32_read_quad_z(struct softpipe_surface *sps,
+                GLint x, GLint y, GLuint zzzz[QUAD_SIZE])
+{
+   const GLuint *src
+      = (GLuint *) sps->surface.ptr + y * sps->surface.stride + x;
+
+   assert(sps->surface.format == PIPE_FORMAT_U_Z32);
+
+   zzzz[0] = src[0];
+   zzzz[1] = src[1];
+   zzzz[2] = src[sps->surface.width + 0];
+   zzzz[3] = src[sps->surface.width + 1];
+}
+
+static void
+z32_write_quad_z(struct softpipe_surface *sps,
+                 GLint x, GLint y, const GLuint zzzz[QUAD_SIZE])
+{
+   GLuint *dst = (GLuint *) sps->surface.ptr + y * sps->surface.stride + x;
+
+   assert(sps->surface.format == PIPE_FORMAT_U_Z32);
+
+   dst[0] = zzzz[0];
+   dst[1] = zzzz[1];
+   dst[sps->surface.width + 0] = zzzz[2];
+   dst[sps->surface.width + 1] = zzzz[3];
+}
+
+static void
+z24s8_read_quad_z(struct softpipe_surface *sps,
+                  GLint x, GLint y, GLuint zzzz[QUAD_SIZE])
+{
+   const GLuint *src
+      = (GLuint *) sps->surface.ptr + y * sps->surface.stride + x;
+
+   assert(sps->surface.format == PIPE_FORMAT_Z24_S8);
+
+   zzzz[0] = src[0] >> 8;
+   zzzz[1] = src[1] >> 8;
+   zzzz[2] = src[sps->surface.width + 0] >> 8;
+   zzzz[3] = src[sps->surface.width + 1] >> 8;
+}
+
+static void
+z24s8_write_quad_z(struct softpipe_surface *sps,
+                   GLint x, GLint y, const GLuint zzzz[QUAD_SIZE])
+{
+   GLuint *dst = (GLuint *) sps->surface.ptr + y * sps->surface.stride + x;
+
+   assert(sps->surface.format == PIPE_FORMAT_Z24_S8);
+   assert(zzzz[0] <= 0xffffff);
+
+   dst[0] = (dst[0] & 0xff) | (zzzz[0] << 8);
+   dst[1] = (dst[1] & 0xff) | (zzzz[1] << 8);
+   dst += sps->surface.width;
+   dst[0] = (dst[0] & 0xff) | (zzzz[2] << 8);
+   dst[1] = (dst[1] & 0xff) | (zzzz[3] << 8);
+}
+
+static void
+z24s8_read_quad_stencil(struct softpipe_surface *sps,
+                        GLint x, GLint y, GLubyte ssss[QUAD_SIZE])
+{
+   const GLuint *src
+      = (GLuint *) sps->surface.ptr + y * sps->surface.stride + x;
+
+   assert(sps->surface.format == PIPE_FORMAT_Z24_S8);
+
+   ssss[0] = src[0] & 0xff;
+   ssss[1] = src[1] & 0xff;
+   ssss[2] = src[sps->surface.width + 0] & 0xff;
+   ssss[3] = src[sps->surface.width + 1] & 0xff;
+}
+
+static void
+z24s8_write_quad_stencil(struct softpipe_surface *sps,
+                         GLint x, GLint y, const GLubyte ssss[QUAD_SIZE])
+{
+   GLuint *dst = (GLuint *) sps->surface.ptr + y * sps->surface.stride + x;
+
+   assert(sps->surface.format == PIPE_FORMAT_Z24_S8);
+
+   dst[0] = (dst[0] & 0xffffff00) | ssss[0];
+   dst[1] = (dst[1] & 0xffffff00) | ssss[1];
+   dst += sps->surface.width;
+   dst[0] = (dst[0] & 0xffffff00) | ssss[2];
+   dst[1] = (dst[1] & 0xffffff00) | ssss[3];
+}
+
+
+
+/**
+ * Create a new software-based Z buffer.
+ * \param format  one of the PIPE_FORMAT_z* formats
+ */
+struct softpipe_surface *
+softpipe_new_z_surface(GLuint format)
+{
+   struct softpipe_surface *sps = CALLOC_STRUCT(softpipe_surface);
+   if (!sps)
+      return NULL;
+
+   sps->surface.format = format;
+   sps->surface.resize = z_resize;
+   sps->surface.buffer.map = z_map;
+   sps->surface.buffer.unmap = z_unmap;
+
+   if (format == PIPE_FORMAT_U_Z16) {
+      sps->read_quad_z = z16_read_quad_z;
+      sps->write_quad_z = z16_write_quad_z;
+   }
+   else if (format == PIPE_FORMAT_U_Z32) {
+      sps->read_quad_z = z32_read_quad_z;
+      sps->write_quad_z = z32_write_quad_z;
+   }
+   else if (format == PIPE_FORMAT_Z24_S8) {
+      sps->read_quad_z = z24s8_read_quad_z;
+      sps->write_quad_z = z24s8_write_quad_z;
+      sps->read_quad_stencil = z24s8_read_quad_stencil;
+      sps->write_quad_stencil = z24s8_write_quad_stencil;
+   }
+   else {
+      assert(0);
+   }
+
+   return sps;
+}
diff --git a/src/mesa/pipe/softpipe/sp_z_surface.h b/src/mesa/pipe/softpipe/sp_z_surface.h
new file mode 100644 (file)
index 0000000..6a8d89a
--- /dev/null
@@ -0,0 +1,37 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+
+#ifndef SP_Z_SURFACE_H
+#define SP_Z_SURFACE_H
+
+
+extern struct softpipe_surface *
+softpipe_new_z_surface(GLuint format);
+
+
+#endif /* SP_Z_SURFACE_H */
diff --git a/src/mesa/pipe/tgsi/Makefile b/src/mesa/pipe/tgsi/Makefile
new file mode 100644 (file)
index 0000000..12a8bd0
--- /dev/null
@@ -0,0 +1,3 @@
+default:
+       cd ../.. ; make
+
diff --git a/src/mesa/pipe/tgsi/core/Makefile b/src/mesa/pipe/tgsi/core/Makefile
new file mode 100644 (file)
index 0000000..eb8b14e
--- /dev/null
@@ -0,0 +1,3 @@
+default:
+       cd ../../.. ; make
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_build.c b/src/mesa/pipe/tgsi/core/tgsi_build.c
new file mode 100644 (file)
index 0000000..2a482a7
--- /dev/null
@@ -0,0 +1,1315 @@
+#include "tgsi_platform.h"
+#include "tgsi_core.h"
+
+/*
+ * version
+ */
+
+struct tgsi_version
+tgsi_build_version( void )
+{
+   struct tgsi_version  version;
+
+   version.MajorVersion = 1;
+   version.MinorVersion = 1;
+   version.Padding = 0;
+
+   return version;
+}
+
+/*
+ * header
+ */
+
+struct tgsi_header
+tgsi_build_header( void )
+{
+   struct tgsi_header header;
+
+   header.HeaderSize = 1;
+   header.BodySize = 0;
+
+   return header;
+}
+
+static void
+header_headersize_grow( struct tgsi_header *header )
+{
+   assert (header->HeaderSize < 0xFF);
+   assert (header->BodySize == 0);
+
+   header->HeaderSize++;
+}
+
+static void
+header_bodysize_grow( struct tgsi_header *header )
+{
+   assert (header->BodySize < 0xFFFFFF);
+
+   header->BodySize++;
+}
+
+struct tgsi_processor
+tgsi_default_processor( void )
+{
+   struct tgsi_processor processor;
+
+   processor.Processor = TGSI_PROCESSOR_FRAGMENT;
+   processor.Padding = 0;
+
+   return processor;
+}
+
+struct tgsi_processor
+tgsi_build_processor(
+   GLuint type,
+   struct tgsi_header *header )
+{
+   struct tgsi_processor processor;
+
+   processor = tgsi_default_processor();
+   processor.Processor = type;
+
+   header_headersize_grow( header );
+
+   return processor;
+}
+
+/*
+ * declaration
+ */
+
+struct tgsi_declaration
+tgsi_default_declaration( void )
+{
+   struct tgsi_declaration declaration;
+
+   declaration.Type = TGSI_TOKEN_TYPE_DECLARATION;
+   declaration.Size = 1;
+   declaration.File = TGSI_FILE_NULL;
+   declaration.Declare = TGSI_DECLARE_RANGE;
+   declaration.Interpolate = 0;
+   declaration.Padding = 0;
+   declaration.Extended = 0;
+
+   return declaration;
+}
+
+struct tgsi_declaration
+tgsi_build_declaration(
+   GLuint file,
+   GLuint declare,
+   GLuint interpolate,
+   struct tgsi_header *header )
+{
+   struct tgsi_declaration declaration;
+
+   assert (file <= TGSI_FILE_IMMEDIATE);
+   assert (declare <= TGSI_DECLARE_MASK);
+
+   declaration = tgsi_default_declaration();
+   declaration.File = file;
+   declaration.Declare = declare;
+   declaration.Interpolate = interpolate;
+
+   header_bodysize_grow( header );
+
+   return declaration;
+}
+
+static void
+declaration_grow(
+   struct tgsi_declaration *declaration,
+   struct tgsi_header *header )
+{
+   assert (declaration->Size < 0xFF);
+
+   declaration->Size++;
+
+   header_bodysize_grow( header );
+}
+
+struct tgsi_full_declaration
+tgsi_default_full_declaration( void )
+{
+   struct tgsi_full_declaration  full_declaration;
+
+   full_declaration.Declaration  = tgsi_default_declaration();
+   full_declaration.Interpolation = tgsi_default_declaration_interpolation();
+
+   return full_declaration;
+}
+
+GLuint
+tgsi_build_full_declaration(
+   const struct   tgsi_full_declaration *full_decl,
+   struct tgsi_token *tokens,
+   struct tgsi_header *header,
+   GLuint maxsize )
+{
+   GLuint size = 0;
+   struct tgsi_declaration *declaration;
+
+   if( maxsize <= size )
+     return 0;
+   declaration = (struct tgsi_declaration *) &tokens[size];
+   size++;
+
+   *declaration = tgsi_build_declaration(
+      full_decl->Declaration.File,
+      full_decl->Declaration.Declare,
+      full_decl->Declaration.Interpolate,
+      header );
+
+   switch( full_decl->Declaration.Declare )  {
+   case  TGSI_DECLARE_RANGE:
+   {
+      struct tgsi_declaration_range *dr;
+
+      if( maxsize <=   size )
+         return 0;
+      dr = (struct tgsi_declaration_range *) &tokens[size];
+      size++;
+
+      *dr = tgsi_build_declaration_range(
+         full_decl->u.DeclarationRange.First,
+         full_decl->u.DeclarationRange.Last,
+         declaration,
+         header );
+      break;
+    }
+
+   case  TGSI_DECLARE_MASK:
+   {
+      struct  tgsi_declaration_mask *dm;
+
+      if( maxsize <=   size )
+         return 0;
+      dm = (struct tgsi_declaration_mask  *) &tokens[size];
+      size++;
+
+      *dm = tgsi_build_declaration_mask(
+         full_decl->u.DeclarationMask.Mask,
+         declaration,
+         header );
+      break;
+   }
+
+   default:
+      assert( 0 );
+   }
+
+   if( full_decl->Declaration.Interpolate ) {
+      struct tgsi_declaration_interpolation *di;
+
+      if( maxsize <= size )
+         return  0;
+      di = (struct tgsi_declaration_interpolation *) &tokens[size];
+      size++;
+
+      *di = tgsi_build_declaration_interpolation(
+         full_decl->Interpolation.Interpolate,
+         declaration,
+         header );
+   }
+
+   return size;
+}
+
+struct tgsi_declaration_range
+tgsi_build_declaration_range(
+   GLuint first,
+   GLuint last,
+   struct tgsi_declaration *declaration,
+   struct tgsi_header *header )
+{
+   struct tgsi_declaration_range declaration_range;
+
+   assert (last >=   first);
+   assert (last <=   0xFFFF);
+
+   declaration_range.First = first;
+   declaration_range.Last = last;
+
+   declaration_grow( declaration, header );
+
+   return declaration_range;
+}
+
+struct tgsi_declaration_mask
+tgsi_build_declaration_mask(
+   GLuint mask,
+   struct tgsi_declaration *declaration,
+   struct tgsi_header *header )
+{
+   struct tgsi_declaration_mask  declaration_mask;
+
+   declaration_mask.Mask = mask;
+
+   declaration_grow( declaration, header );
+
+   return declaration_mask;
+}
+
+struct tgsi_declaration_interpolation
+tgsi_default_declaration_interpolation( void )
+{
+   struct tgsi_declaration_interpolation di;
+
+   di.Interpolate = TGSI_INTERPOLATE_CONSTANT;
+   di.Padding = 0;
+
+   return di;
+}
+
+struct tgsi_declaration_interpolation
+tgsi_build_declaration_interpolation(
+   GLuint interpolate,
+   struct tgsi_declaration *declaration,
+   struct tgsi_header *header )
+{
+   struct tgsi_declaration_interpolation di;
+
+   assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE );
+
+   di = tgsi_default_declaration_interpolation();
+   di.Interpolate = interpolate;
+
+   declaration_grow( declaration, header );
+
+   return di;
+}
+
+/*
+ * immediate
+ */
+
+struct tgsi_immediate
+tgsi_default_immediate( void )
+{
+   struct tgsi_immediate immediate;
+
+   immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
+   immediate.Size = 1;
+   immediate.DataType = TGSI_IMM_FLOAT32;
+   immediate.Padding = 0;
+   immediate.Extended = 0;
+
+   return immediate;
+}
+
+struct tgsi_immediate
+tgsi_build_immediate(
+   struct tgsi_header *header )
+{
+   struct tgsi_immediate immediate;
+
+   immediate = tgsi_default_immediate();
+
+   header_bodysize_grow( header  );
+
+   return immediate;
+}
+
+struct tgsi_full_immediate
+tgsi_default_full_immediate( void )
+{
+   struct tgsi_full_immediate fullimm;
+
+   fullimm.Immediate = tgsi_default_immediate();
+   fullimm.u.Pointer = (void *) 0;
+
+   return fullimm;
+}
+
+static void
+immediate_grow(
+   struct tgsi_immediate *immediate,
+   struct tgsi_header *header )
+{
+   assert( immediate->Size < 0xFF );
+
+   immediate->Size++;
+
+   header_bodysize_grow( header );
+}
+
+struct tgsi_immediate_float32
+tgsi_build_immediate_float32(
+   GLfloat value,
+   struct tgsi_immediate *immediate,
+   struct tgsi_header *header )
+{
+   struct tgsi_immediate_float32 immediate_float32;
+
+   immediate_float32.Float = value;
+
+   immediate_grow( immediate, header );
+
+   return immediate_float32;
+}
+
+GLuint
+tgsi_build_full_immediate(
+   const struct tgsi_full_immediate *full_imm,
+   struct tgsi_token *tokens,
+   struct tgsi_header *header,
+   GLuint maxsize )
+{
+   GLuint size = 0,  i;
+   struct tgsi_immediate *immediate;
+
+   if( maxsize <= size )
+      return 0;
+   immediate = (struct tgsi_immediate *) &tokens[size];
+   size++;
+
+   *immediate = tgsi_build_immediate( header );
+
+   for( i = 0; i < full_imm->Immediate.Size - 1; i++ ) {
+      struct tgsi_immediate_float32 *if32;
+
+      if( maxsize <= size )
+         return  0;
+      if32 = (struct tgsi_immediate_float32 *) &tokens[size];
+      size++;
+
+      *if32  = tgsi_build_immediate_float32(
+         full_imm->u.ImmediateFloat32[i].Float,
+         immediate,
+         header );
+   }
+
+   return size;
+}
+
+/*
+ * instruction
+ */
+
+struct tgsi_instruction
+tgsi_default_instruction( void )
+{
+   struct tgsi_instruction instruction;
+
+   instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
+   instruction.Size = 1;
+   instruction.Opcode = TGSI_OPCODE_MOV;
+   instruction.Saturate = TGSI_SAT_NONE;
+   instruction.NumDstRegs = 1;
+   instruction.NumSrcRegs = 1;
+   instruction.Padding  = 0;
+   instruction.Extended = 0;
+
+   return instruction;
+}
+
+struct tgsi_instruction
+tgsi_build_instruction(
+   GLuint opcode,
+   GLuint saturate,
+   GLuint num_dst_regs,
+   GLuint num_src_regs,
+   struct tgsi_header *header )
+{
+   struct tgsi_instruction instruction;
+
+   assert (opcode <= TGSI_OPCODE_LAST);
+   assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE);
+   assert (num_dst_regs <= 3);
+   assert (num_src_regs <= 15);
+
+   instruction = tgsi_default_instruction();
+   instruction.Opcode = opcode;
+   instruction.Saturate = saturate;
+   instruction.NumDstRegs = num_dst_regs;
+   instruction.NumSrcRegs = num_src_regs;
+
+   header_bodysize_grow( header );
+
+   return instruction;
+}
+
+static void
+instruction_grow(
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header )
+{
+   assert (instruction->Size <   0xFF);
+
+   instruction->Size++;
+
+   header_bodysize_grow( header );
+}
+
+struct tgsi_full_instruction
+tgsi_default_full_instruction( void )
+{
+   struct tgsi_full_instruction full_instruction;
+   GLuint i;
+
+   full_instruction.Instruction = tgsi_default_instruction();
+   full_instruction.InstructionExtNv = tgsi_default_instruction_ext_nv();
+   full_instruction.InstructionExtLabel = tgsi_default_instruction_ext_label();
+   full_instruction.InstructionExtTexture = tgsi_default_instruction_ext_texture();
+   for( i = 0;  i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
+      full_instruction.FullDstRegisters[i] = tgsi_default_full_dst_register();
+   }
+   for( i = 0;  i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) {
+      full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register();
+   }
+
+   return full_instruction;
+}
+
+GLuint
+tgsi_build_full_instruction(
+   const struct tgsi_full_instruction *full_inst,
+   struct  tgsi_token *tokens,
+   struct  tgsi_header *header,
+   GLuint  maxsize )
+{
+   GLuint size = 0;
+   GLuint i;
+   struct tgsi_instruction *instruction;
+   struct tgsi_token *prev_token;
+
+   if( maxsize <= size )
+      return 0;
+   instruction = (struct tgsi_instruction *) &tokens[size];
+   size++;
+
+   *instruction = tgsi_build_instruction(
+      full_inst->Instruction.Opcode,
+      full_inst->Instruction.Saturate,
+      full_inst->Instruction.NumDstRegs,
+      full_inst->Instruction.NumSrcRegs,
+      header );
+   prev_token = (struct tgsi_token  *) instruction;
+
+   if( tgsi_compare_instruction_ext_nv(
+         full_inst->InstructionExtNv,
+         tgsi_default_instruction_ext_nv() ) ) {
+      struct tgsi_instruction_ext_nv *instruction_ext_nv;
+
+      if( maxsize <= size )
+         return 0;
+      instruction_ext_nv =
+         (struct  tgsi_instruction_ext_nv *) &tokens[size];
+      size++;
+
+      *instruction_ext_nv  = tgsi_build_instruction_ext_nv(
+         full_inst->InstructionExtNv.Precision,
+         full_inst->InstructionExtNv.CondDstIndex,
+         full_inst->InstructionExtNv.CondFlowIndex,
+         full_inst->InstructionExtNv.CondMask,
+         full_inst->InstructionExtNv.CondSwizzleX,
+         full_inst->InstructionExtNv.CondSwizzleY,
+         full_inst->InstructionExtNv.CondSwizzleZ,
+         full_inst->InstructionExtNv.CondSwizzleW,
+         full_inst->InstructionExtNv.CondDstUpdate,
+         full_inst->InstructionExtNv.CondFlowEnable,
+         prev_token,
+         instruction,
+         header );
+      prev_token = (struct tgsi_token  *) instruction_ext_nv;
+   }
+
+   if( tgsi_compare_instruction_ext_label(
+         full_inst->InstructionExtLabel,
+         tgsi_default_instruction_ext_label() ) ) {
+      struct tgsi_instruction_ext_label *instruction_ext_label;
+
+      if( maxsize <= size )
+         return 0;
+      instruction_ext_label =
+         (struct  tgsi_instruction_ext_label *) &tokens[size];
+      size++;
+
+      *instruction_ext_label = tgsi_build_instruction_ext_label(
+         full_inst->InstructionExtLabel.Label,
+         full_inst->InstructionExtLabel.Target,
+         prev_token,
+         instruction,
+         header );
+      prev_token = (struct tgsi_token  *) instruction_ext_label;
+   }
+
+   if( tgsi_compare_instruction_ext_texture(
+         full_inst->InstructionExtTexture,
+         tgsi_default_instruction_ext_texture() ) ) {
+      struct tgsi_instruction_ext_texture *instruction_ext_texture;
+
+      if( maxsize <= size )
+         return 0;
+      instruction_ext_texture =
+         (struct  tgsi_instruction_ext_texture *) &tokens[size];
+      size++;
+
+      *instruction_ext_texture = tgsi_build_instruction_ext_texture(
+         full_inst->InstructionExtTexture.Texture,
+         prev_token,
+         instruction,
+         header   );
+      prev_token = (struct tgsi_token  *) instruction_ext_texture;
+   }
+
+   for( i = 0;  i <   full_inst->Instruction.NumDstRegs; i++ ) {
+      const struct tgsi_full_dst_register *reg = &full_inst->FullDstRegisters[i];
+      struct tgsi_dst_register *dst_register;
+      struct tgsi_token *prev_token;
+
+      if( maxsize <= size )
+         return 0;
+      dst_register = (struct tgsi_dst_register *) &tokens[size];
+      size++;
+
+      *dst_register = tgsi_build_dst_register(
+         reg->DstRegister.File,
+         reg->DstRegister.WriteMask,
+         reg->DstRegister.Index,
+         instruction,
+         header );
+      prev_token = (struct tgsi_token  *) dst_register;
+
+      if( tgsi_compare_dst_register_ext_concode(
+            reg->DstRegisterExtConcode,
+            tgsi_default_dst_register_ext_concode() ) ) {
+         struct tgsi_dst_register_ext_concode *dst_register_ext_concode;
+
+         if( maxsize <= size )
+            return 0;
+         dst_register_ext_concode =
+            (struct  tgsi_dst_register_ext_concode *) &tokens[size];
+         size++;
+
+         *dst_register_ext_concode =   tgsi_build_dst_register_ext_concode(
+            reg->DstRegisterExtConcode.CondMask,
+            reg->DstRegisterExtConcode.CondSwizzleX,
+            reg->DstRegisterExtConcode.CondSwizzleY,
+            reg->DstRegisterExtConcode.CondSwizzleZ,
+            reg->DstRegisterExtConcode.CondSwizzleW,
+            reg->DstRegisterExtConcode.CondSrcIndex,
+            prev_token,
+            instruction,
+            header );
+         prev_token = (struct tgsi_token  *) dst_register_ext_concode;
+      }
+
+      if( tgsi_compare_dst_register_ext_modulate(
+            reg->DstRegisterExtModulate,
+            tgsi_default_dst_register_ext_modulate() ) ) {
+         struct tgsi_dst_register_ext_modulate *dst_register_ext_modulate;
+
+         if( maxsize <= size )
+            return 0;
+         dst_register_ext_modulate =
+            (struct  tgsi_dst_register_ext_modulate *) &tokens[size];
+         size++;
+
+         *dst_register_ext_modulate = tgsi_build_dst_register_ext_modulate(
+            reg->DstRegisterExtModulate.Modulate,
+            prev_token,
+            instruction,
+            header );
+         prev_token = (struct tgsi_token  *) dst_register_ext_modulate;
+      }
+   }
+
+   for( i = 0;  i < full_inst->Instruction.NumSrcRegs; i++ ) {
+      const struct tgsi_full_src_register *reg = &full_inst->FullSrcRegisters[i];
+      struct tgsi_src_register *src_register;
+      struct tgsi_token *prev_token;
+
+      if( maxsize <= size )
+         return 0;
+      src_register = (struct tgsi_src_register *)  &tokens[size];
+      size++;
+
+      *src_register = tgsi_build_src_register(
+         reg->SrcRegister.File,
+         reg->SrcRegister.SwizzleX,
+         reg->SrcRegister.SwizzleY,
+         reg->SrcRegister.SwizzleZ,
+         reg->SrcRegister.SwizzleW,
+         reg->SrcRegister.Negate,
+         reg->SrcRegister.Indirect,
+         reg->SrcRegister.Dimension,
+         reg->SrcRegister.Index,
+         instruction,
+         header );
+      prev_token = (struct tgsi_token  *) src_register;
+
+      if( tgsi_compare_src_register_ext_swz(
+            reg->SrcRegisterExtSwz,
+            tgsi_default_src_register_ext_swz() ) ) {
+         struct tgsi_src_register_ext_swz *src_register_ext_swz;
+
+         if( maxsize <= size )
+            return 0;
+         src_register_ext_swz =
+            (struct  tgsi_src_register_ext_swz *) &tokens[size];
+         size++;
+
+         *src_register_ext_swz = tgsi_build_src_register_ext_swz(
+            reg->SrcRegisterExtSwz.ExtSwizzleX,
+            reg->SrcRegisterExtSwz.ExtSwizzleY,
+            reg->SrcRegisterExtSwz.ExtSwizzleZ,
+            reg->SrcRegisterExtSwz.ExtSwizzleW,
+            reg->SrcRegisterExtSwz.NegateX,
+            reg->SrcRegisterExtSwz.NegateY,
+            reg->SrcRegisterExtSwz.NegateZ,
+            reg->SrcRegisterExtSwz.NegateW,
+            reg->SrcRegisterExtSwz.ExtDivide,
+            prev_token,
+            instruction,
+            header );
+         prev_token = (struct tgsi_token  *) src_register_ext_swz;
+      }
+
+      if( tgsi_compare_src_register_ext_mod(
+            reg->SrcRegisterExtMod,
+            tgsi_default_src_register_ext_mod() ) ) {
+         struct tgsi_src_register_ext_mod *src_register_ext_mod;
+
+         if( maxsize <= size )
+            return 0;
+         src_register_ext_mod =
+            (struct  tgsi_src_register_ext_mod *) &tokens[size];
+         size++;
+
+         *src_register_ext_mod = tgsi_build_src_register_ext_mod(
+            reg->SrcRegisterExtMod.Complement,
+            reg->SrcRegisterExtMod.Bias,
+            reg->SrcRegisterExtMod.Scale2X,
+            reg->SrcRegisterExtMod.Absolute,
+            reg->SrcRegisterExtMod.Negate,
+            prev_token,
+            instruction,
+            header );
+         prev_token = (struct tgsi_token  *) src_register_ext_mod;
+      }
+
+      if( reg->SrcRegister.Indirect ) {
+         struct  tgsi_src_register *ind;
+
+         if( maxsize <= size )
+            return 0;
+         ind = (struct tgsi_src_register *) &tokens[size];
+         size++;
+
+         *ind = tgsi_build_src_register(
+            reg->SrcRegisterInd.File,
+            reg->SrcRegisterInd.SwizzleX,
+            reg->SrcRegisterInd.SwizzleY,
+            reg->SrcRegisterInd.SwizzleZ,
+            reg->SrcRegisterInd.SwizzleW,
+            reg->SrcRegisterInd.Negate,
+            reg->SrcRegisterInd.Indirect,
+            reg->SrcRegisterInd.Dimension,
+            reg->SrcRegisterInd.Index,
+            instruction,
+            header );
+      }
+
+      if( reg->SrcRegister.Dimension ) {
+         struct  tgsi_dimension *dim;
+
+         assert( !reg->SrcRegisterDim.Dimension );
+
+         if( maxsize <= size )
+            return 0;
+         dim = (struct tgsi_dimension *) &tokens[size];
+         size++;
+
+         *dim = tgsi_build_dimension(
+            reg->SrcRegisterDim.Indirect,
+            reg->SrcRegisterDim.Index,
+            instruction,
+            header );
+
+         if( reg->SrcRegisterDim.Indirect ) {
+            struct tgsi_src_register *ind;
+
+            if( maxsize <= size )
+               return 0;
+            ind = (struct tgsi_src_register *) &tokens[size];
+            size++;
+
+            *ind = tgsi_build_src_register(
+               reg->SrcRegisterDimInd.File,
+               reg->SrcRegisterDimInd.SwizzleX,
+               reg->SrcRegisterDimInd.SwizzleY,
+               reg->SrcRegisterDimInd.SwizzleZ,
+               reg->SrcRegisterDimInd.SwizzleW,
+               reg->SrcRegisterDimInd.Negate,
+               reg->SrcRegisterDimInd.Indirect,
+               reg->SrcRegisterDimInd.Dimension,
+               reg->SrcRegisterDimInd.Index,
+               instruction,
+               header );
+         }
+      }
+   }
+
+   return size;
+}
+
+struct tgsi_instruction_ext_nv
+tgsi_default_instruction_ext_nv( void )
+{
+   struct tgsi_instruction_ext_nv instruction_ext_nv;
+
+   instruction_ext_nv.Type = TGSI_INSTRUCTION_EXT_TYPE_NV;
+   instruction_ext_nv.Precision = TGSI_PRECISION_DEFAULT;
+   instruction_ext_nv.CondDstIndex = 0;
+   instruction_ext_nv.CondFlowIndex = 0;
+   instruction_ext_nv.CondMask = TGSI_CC_TR;
+   instruction_ext_nv.CondSwizzleX = TGSI_SWIZZLE_X;
+   instruction_ext_nv.CondSwizzleY = TGSI_SWIZZLE_Y;
+   instruction_ext_nv.CondSwizzleZ = TGSI_SWIZZLE_Z;
+   instruction_ext_nv.CondSwizzleW = TGSI_SWIZZLE_W;
+   instruction_ext_nv.CondDstUpdate = 0;
+   instruction_ext_nv.CondFlowEnable = 0;
+   instruction_ext_nv.Padding = 0;
+   instruction_ext_nv.Extended = 0;
+
+   return instruction_ext_nv;
+}
+
+union token_u32
+{
+   GLuint   u32;
+};
+
+GLuint
+tgsi_compare_instruction_ext_nv(
+   struct tgsi_instruction_ext_nv a,
+   struct tgsi_instruction_ext_nv b )
+{
+   a.Padding = b.Padding = 0;
+   a.Extended = b.Extended = 0;
+   return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32;
+}
+
+struct tgsi_instruction_ext_nv
+tgsi_build_instruction_ext_nv(
+   GLuint precision,
+   GLuint cond_dst_index,
+   GLuint cond_flow_index,
+   GLuint cond_mask,
+   GLuint cond_swizzle_x,
+   GLuint cond_swizzle_y,
+   GLuint cond_swizzle_z,
+   GLuint cond_swizzle_w,
+   GLuint cond_dst_update,
+   GLuint cond_flow_update,
+   struct tgsi_token *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header )
+{
+   struct tgsi_instruction_ext_nv instruction_ext_nv;
+
+   instruction_ext_nv = tgsi_default_instruction_ext_nv();
+   instruction_ext_nv.Precision = precision;
+   instruction_ext_nv.CondDstIndex = cond_dst_index;
+   instruction_ext_nv.CondFlowIndex = cond_flow_index;
+   instruction_ext_nv.CondMask = cond_mask;
+   instruction_ext_nv.CondSwizzleX = cond_swizzle_x;
+   instruction_ext_nv.CondSwizzleY = cond_swizzle_y;
+   instruction_ext_nv.CondSwizzleZ = cond_swizzle_z;
+   instruction_ext_nv.CondSwizzleW = cond_swizzle_w;
+   instruction_ext_nv.CondDstUpdate = cond_dst_update;
+   instruction_ext_nv.CondFlowEnable = cond_flow_update;
+
+   prev_token->Extended = 1;
+   instruction_grow( instruction, header );
+
+   return instruction_ext_nv;
+}
+
+struct tgsi_instruction_ext_label
+tgsi_default_instruction_ext_label( void )
+{
+   struct tgsi_instruction_ext_label instruction_ext_label;
+
+   instruction_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL;
+   instruction_ext_label.Label = 0;
+   instruction_ext_label.Target = 0;
+   instruction_ext_label.Padding = 0;
+   instruction_ext_label.Extended = 0;
+
+   return instruction_ext_label;
+}
+
+GLuint
+tgsi_compare_instruction_ext_label(
+   struct tgsi_instruction_ext_label a,
+   struct tgsi_instruction_ext_label b )
+{
+   a.Padding = b.Padding = 0;
+   a.Extended = b.Extended = 0;
+   return *(GLuint *) &a != *(GLuint *) &b;
+}
+
+struct tgsi_instruction_ext_label
+tgsi_build_instruction_ext_label(
+   GLuint label,
+   GLuint target,
+   struct tgsi_token  *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header )
+{
+   struct tgsi_instruction_ext_label instruction_ext_label;
+
+   instruction_ext_label = tgsi_default_instruction_ext_label();
+   instruction_ext_label.Label = label;
+   instruction_ext_label.Target = target;
+
+   prev_token->Extended = 1;
+   instruction_grow( instruction, header );
+
+   return instruction_ext_label;
+}
+
+struct tgsi_instruction_ext_texture
+tgsi_default_instruction_ext_texture( void )
+{
+   struct tgsi_instruction_ext_texture instruction_ext_texture;
+
+   instruction_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE;
+   instruction_ext_texture.Texture = TGSI_TEXTURE_UNKNOWN;
+   instruction_ext_texture.Padding = 0;
+   instruction_ext_texture.Extended = 0;
+
+   return instruction_ext_texture;
+}
+
+GLuint
+tgsi_compare_instruction_ext_texture(
+   struct tgsi_instruction_ext_texture a,
+   struct tgsi_instruction_ext_texture b )
+{
+   a.Padding = b.Padding = 0;
+   a.Extended = b.Extended = 0;
+   return *(GLuint *) &a != *(GLuint *) &b;
+}
+
+struct tgsi_instruction_ext_texture
+tgsi_build_instruction_ext_texture(
+   GLuint texture,
+   struct tgsi_token *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header )
+{
+   struct tgsi_instruction_ext_texture instruction_ext_texture;
+
+   instruction_ext_texture = tgsi_default_instruction_ext_texture();
+   instruction_ext_texture.Texture = texture;
+
+   prev_token->Extended = 1;
+   instruction_grow( instruction, header );
+
+   return instruction_ext_texture;
+}
+
+struct tgsi_src_register
+tgsi_default_src_register( void )
+{
+   struct tgsi_src_register src_register;
+
+   src_register.File = TGSI_FILE_NULL;
+   src_register.SwizzleX = TGSI_SWIZZLE_X;
+   src_register.SwizzleY = TGSI_SWIZZLE_Y;
+   src_register.SwizzleZ = TGSI_SWIZZLE_Z;
+   src_register.SwizzleW = TGSI_SWIZZLE_W;
+   src_register.Negate = 0;
+   src_register.Indirect = 0;
+   src_register.Dimension = 0;
+   src_register.Index = 0;
+   src_register.Extended = 0;
+
+   return src_register;
+}
+
+struct tgsi_src_register
+tgsi_build_src_register(
+   GLuint file,
+   GLuint swizzle_x,
+   GLuint swizzle_y,
+   GLuint swizzle_z,
+   GLuint swizzle_w,
+   GLuint negate,
+   GLuint indirect,
+   GLuint dimension,
+   GLint index,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header )
+{
+   struct tgsi_src_register   src_register;
+
+   assert( file <= TGSI_FILE_IMMEDIATE );
+   assert( swizzle_x <= TGSI_SWIZZLE_W );
+   assert( swizzle_y <= TGSI_SWIZZLE_W );
+   assert( swizzle_z <= TGSI_SWIZZLE_W );
+   assert( swizzle_w <= TGSI_SWIZZLE_W );
+   assert( negate <= 1 );
+   assert( index >= -0x8000 && index <= 0x7FFF );
+
+   src_register = tgsi_default_src_register();
+   src_register.File = file;
+   src_register.SwizzleX = swizzle_x;
+   src_register.SwizzleY = swizzle_y;
+   src_register.SwizzleZ = swizzle_z;
+   src_register.SwizzleW = swizzle_w;
+   src_register.Negate = negate;
+   src_register.Indirect = indirect;
+   src_register.Dimension = dimension;
+   src_register.Index = index;
+
+   instruction_grow( instruction, header );
+
+   return src_register;
+}
+
+struct tgsi_full_src_register
+tgsi_default_full_src_register( void )
+{
+   struct tgsi_full_src_register full_src_register;
+
+   full_src_register.SrcRegister = tgsi_default_src_register();
+   full_src_register.SrcRegisterExtSwz = tgsi_default_src_register_ext_swz();
+   full_src_register.SrcRegisterExtMod = tgsi_default_src_register_ext_mod();
+   full_src_register.SrcRegisterInd = tgsi_default_src_register();
+   full_src_register.SrcRegisterDim = tgsi_default_dimension();
+   full_src_register.SrcRegisterDimInd = tgsi_default_src_register();
+
+   return full_src_register;
+}
+
+struct tgsi_src_register_ext_swz
+tgsi_default_src_register_ext_swz( void )
+{
+   struct tgsi_src_register_ext_swz src_register_ext_swz;
+
+   src_register_ext_swz.Type = TGSI_SRC_REGISTER_EXT_TYPE_SWZ;
+   src_register_ext_swz.ExtSwizzleX = TGSI_EXTSWIZZLE_X;
+   src_register_ext_swz.ExtSwizzleY = TGSI_EXTSWIZZLE_Y;
+   src_register_ext_swz.ExtSwizzleZ = TGSI_EXTSWIZZLE_Z;
+   src_register_ext_swz.ExtSwizzleW = TGSI_EXTSWIZZLE_W;
+   src_register_ext_swz.NegateX = 0;
+   src_register_ext_swz.NegateY = 0;
+   src_register_ext_swz.NegateZ = 0;
+   src_register_ext_swz.NegateW = 0;
+   src_register_ext_swz.ExtDivide = TGSI_EXTSWIZZLE_ONE;
+   src_register_ext_swz.Padding = 0;
+   src_register_ext_swz.Extended = 0;
+
+   return src_register_ext_swz;
+}
+
+GLuint
+tgsi_compare_src_register_ext_swz(
+   struct tgsi_src_register_ext_swz a,
+   struct tgsi_src_register_ext_swz b )
+{
+   a.Padding = b.Padding = 0;
+   a.Extended = b.Extended = 0;
+   return *(GLuint *) &a != *(GLuint *) &b;
+}
+
+struct tgsi_src_register_ext_swz
+tgsi_build_src_register_ext_swz(
+   GLuint ext_swizzle_x,
+   GLuint ext_swizzle_y,
+   GLuint ext_swizzle_z,
+   GLuint ext_swizzle_w,
+   GLuint negate_x,
+   GLuint negate_y,
+   GLuint negate_z,
+   GLuint negate_w,
+   GLuint ext_divide,
+   struct tgsi_token *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header )
+{
+   struct tgsi_src_register_ext_swz src_register_ext_swz;
+
+   assert (ext_swizzle_x <= TGSI_EXTSWIZZLE_ONE);
+   assert (ext_swizzle_y <= TGSI_EXTSWIZZLE_ONE);
+   assert (ext_swizzle_z <= TGSI_EXTSWIZZLE_ONE);
+   assert (ext_swizzle_w <= TGSI_EXTSWIZZLE_ONE);
+   assert (negate_x <= 1);
+   assert (negate_y <= 1);
+   assert (negate_z <= 1);
+   assert (negate_w <= 1);
+   assert (ext_divide <= TGSI_EXTSWIZZLE_ONE);
+
+   src_register_ext_swz = tgsi_default_src_register_ext_swz();
+   src_register_ext_swz.ExtSwizzleX = ext_swizzle_x;
+   src_register_ext_swz.ExtSwizzleY = ext_swizzle_y;
+   src_register_ext_swz.ExtSwizzleZ = ext_swizzle_z;
+   src_register_ext_swz.ExtSwizzleW = ext_swizzle_w;
+   src_register_ext_swz.NegateX = negate_x;
+   src_register_ext_swz.NegateY = negate_y;
+   src_register_ext_swz.NegateZ = negate_z;
+   src_register_ext_swz.NegateW = negate_w;
+   src_register_ext_swz.ExtDivide = ext_divide;
+
+   prev_token->Extended = 1;
+   instruction_grow( instruction, header );
+
+   return src_register_ext_swz;
+}
+
+struct tgsi_src_register_ext_mod
+tgsi_default_src_register_ext_mod( void )
+{
+   struct tgsi_src_register_ext_mod src_register_ext_mod;
+
+   src_register_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD;
+   src_register_ext_mod.Complement = 0;
+   src_register_ext_mod.Bias = 0;
+   src_register_ext_mod.Scale2X = 0;
+   src_register_ext_mod.Absolute = 0;
+   src_register_ext_mod.Negate = 0;
+   src_register_ext_mod.Padding = 0;
+   src_register_ext_mod.Extended = 0;
+
+   return src_register_ext_mod;
+}
+
+GLuint
+tgsi_compare_src_register_ext_mod(
+   struct tgsi_src_register_ext_mod a,
+   struct tgsi_src_register_ext_mod b )
+{
+   a.Padding = b.Padding = 0;
+   a.Extended = b.Extended = 0;
+   return *(GLuint *) &a != *(GLuint *) &b;
+}
+
+struct tgsi_src_register_ext_mod
+tgsi_build_src_register_ext_mod(
+   GLuint  complement,
+   GLuint  bias,
+   GLuint  scale_2x,
+   GLuint  absolute,
+   GLuint  negate,
+   struct  tgsi_token *prev_token,
+   struct  tgsi_instruction *instruction,
+   struct  tgsi_header *header )
+{
+   struct tgsi_src_register_ext_mod src_register_ext_mod;
+
+   assert (complement <= 1);
+   assert (bias <= 1);
+   assert (scale_2x <= 1);
+   assert (absolute <= 1);
+   assert (negate <= 1);
+
+   src_register_ext_mod = tgsi_default_src_register_ext_mod();
+   src_register_ext_mod.Complement = complement;
+   src_register_ext_mod.Bias = bias;
+   src_register_ext_mod.Scale2X = scale_2x;
+   src_register_ext_mod.Absolute = absolute;
+   src_register_ext_mod.Negate = negate;
+
+   prev_token->Extended = 1;
+   instruction_grow( instruction, header );
+
+   return src_register_ext_mod;
+}
+
+struct tgsi_dimension
+tgsi_default_dimension( void )
+{
+   struct tgsi_dimension dimension;
+
+   dimension.Indirect = 0;
+   dimension.Dimension = 0;
+   dimension.Padding = 0;
+   dimension.Index = 0;
+   dimension.Extended = 0;
+
+   return dimension;
+}
+
+struct tgsi_dimension
+tgsi_build_dimension(
+   GLuint indirect,
+   GLuint index,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header )
+{
+   struct tgsi_dimension dimension;
+
+   dimension = tgsi_default_dimension();
+   dimension.Indirect = indirect;
+   dimension.Index = index;
+
+   instruction_grow( instruction, header );
+
+   return dimension;
+}
+
+struct tgsi_dst_register
+tgsi_default_dst_register( void )
+{
+   struct tgsi_dst_register dst_register;
+
+   dst_register.File = TGSI_FILE_NULL;
+   dst_register.WriteMask = TGSI_WRITEMASK_XYZW;
+   dst_register.Indirect = 0;
+   dst_register.Dimension = 0;
+   dst_register.Index = 0;
+   dst_register.Padding = 0;
+   dst_register.Extended = 0;
+
+   return dst_register;
+}
+
+struct tgsi_dst_register
+tgsi_build_dst_register(
+   GLuint file,
+   GLuint mask,
+   GLint index,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header )
+{
+   struct tgsi_dst_register dst_register;
+
+   assert (file <= TGSI_FILE_IMMEDIATE);
+   assert (mask <= TGSI_WRITEMASK_XYZW);
+   assert (index >= -32768 && index <= 32767);
+
+   dst_register = tgsi_default_dst_register();
+   dst_register.File = file;
+   dst_register.WriteMask = mask;
+   dst_register.Index = index;
+
+   instruction_grow( instruction, header );
+
+   return dst_register;
+}
+
+struct tgsi_full_dst_register
+tgsi_default_full_dst_register( void )
+{
+   struct tgsi_full_dst_register full_dst_register;
+
+   full_dst_register.DstRegister = tgsi_default_dst_register();
+   full_dst_register.DstRegisterExtConcode =
+      tgsi_default_dst_register_ext_concode();
+   full_dst_register.DstRegisterExtModulate =
+      tgsi_default_dst_register_ext_modulate();
+
+   return full_dst_register;
+}
+
+struct tgsi_dst_register_ext_concode
+tgsi_default_dst_register_ext_concode( void )
+{
+   struct tgsi_dst_register_ext_concode dst_register_ext_concode;
+
+   dst_register_ext_concode.Type = TGSI_DST_REGISTER_EXT_TYPE_CONDCODE;
+   dst_register_ext_concode.CondMask = TGSI_CC_TR;
+   dst_register_ext_concode.CondSwizzleX = TGSI_SWIZZLE_X;
+   dst_register_ext_concode.CondSwizzleY = TGSI_SWIZZLE_Y;
+   dst_register_ext_concode.CondSwizzleZ = TGSI_SWIZZLE_Z;
+   dst_register_ext_concode.CondSwizzleW = TGSI_SWIZZLE_W;
+   dst_register_ext_concode.CondSrcIndex = 0;
+   dst_register_ext_concode.Padding = 0;
+   dst_register_ext_concode.Extended = 0;
+
+   return dst_register_ext_concode;
+}
+
+GLuint
+tgsi_compare_dst_register_ext_concode(
+   struct tgsi_dst_register_ext_concode a,
+   struct tgsi_dst_register_ext_concode b )
+{
+   a.Padding = b.Padding = 0;
+   a.Extended = b.Extended = 0;
+   return *(GLuint *) &a != *(GLuint *) &b;
+}
+
+struct tgsi_dst_register_ext_concode
+tgsi_build_dst_register_ext_concode(
+   GLuint  cc,
+   GLuint  swizzle_x,
+   GLuint  swizzle_y,
+   GLuint  swizzle_z,
+   GLuint  swizzle_w,
+   GLint index,
+   struct  tgsi_token *prev_token,
+   struct  tgsi_instruction *instruction,
+   struct  tgsi_header *header )
+{
+   struct tgsi_dst_register_ext_concode dst_register_ext_concode;
+
+   assert (cc <= TGSI_CC_FL);
+   assert (swizzle_x <= TGSI_SWIZZLE_W);
+   assert (swizzle_y <= TGSI_SWIZZLE_W);
+   assert (swizzle_z <= TGSI_SWIZZLE_W);
+   assert (swizzle_w <= TGSI_SWIZZLE_W);
+   assert (index >= -32768 && index <= 32767);
+
+   dst_register_ext_concode = tgsi_default_dst_register_ext_concode();
+   dst_register_ext_concode.CondMask = cc;
+   dst_register_ext_concode.CondSwizzleX = swizzle_x;
+   dst_register_ext_concode.CondSwizzleY = swizzle_y;
+   dst_register_ext_concode.CondSwizzleZ = swizzle_z;
+   dst_register_ext_concode.CondSwizzleW = swizzle_w;
+   dst_register_ext_concode.CondSrcIndex = index;
+
+   prev_token->Extended = 1;
+   instruction_grow( instruction, header );
+
+   return dst_register_ext_concode;
+}
+
+struct tgsi_dst_register_ext_modulate
+tgsi_default_dst_register_ext_modulate( void )
+{
+   struct tgsi_dst_register_ext_modulate dst_register_ext_modulate;
+
+   dst_register_ext_modulate.Type = TGSI_DST_REGISTER_EXT_TYPE_MODULATE;
+   dst_register_ext_modulate.Modulate = TGSI_MODULATE_1X;
+   dst_register_ext_modulate.Padding = 0;
+   dst_register_ext_modulate.Extended = 0;
+
+   return dst_register_ext_modulate;
+}
+
+GLuint
+tgsi_compare_dst_register_ext_modulate(
+   struct tgsi_dst_register_ext_modulate a,
+   struct tgsi_dst_register_ext_modulate b )
+{
+   a.Padding = b.Padding = 0;
+   a.Extended = b.Extended = 0;
+   return *(GLuint *) &a != *(GLuint *) &b;
+}
+
+struct tgsi_dst_register_ext_modulate
+tgsi_build_dst_register_ext_modulate(
+   GLuint modulate,
+   struct tgsi_token  *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header )
+{
+   struct tgsi_dst_register_ext_modulate dst_register_ext_modulate;
+
+   assert (modulate <=  TGSI_MODULATE_EIGHTH);
+
+   dst_register_ext_modulate = tgsi_default_dst_register_ext_modulate();
+   dst_register_ext_modulate.Modulate = modulate;
+
+   prev_token->Extended = 1;
+   instruction_grow( instruction, header );
+
+   return dst_register_ext_modulate;
+}
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_build.h b/src/mesa/pipe/tgsi/core/tgsi_build.h
new file mode 100644 (file)
index 0000000..db25956
--- /dev/null
@@ -0,0 +1,309 @@
+#if !defined TGSI_BUILD_H
+#define TGSI_BUILD_H
+
+#if defined __cplusplus
+extern "C" {
+#endif // defined __cplusplus
+
+/*
+ * version
+ */
+
+struct tgsi_version
+tgsi_build_version( void );
+
+/*
+ * header
+ */
+
+struct tgsi_header
+tgsi_build_header( void );
+
+struct tgsi_processor
+tgsi_default_processor( void );
+
+struct tgsi_processor
+tgsi_build_processor(
+   GLuint processor,
+   struct tgsi_header *header );
+
+/*
+ * declaration
+ */
+
+struct tgsi_declaration
+tgsi_default_declaration( void );
+
+struct tgsi_declaration
+tgsi_build_declaration(
+   GLuint file,
+   GLuint declare,
+   GLuint interpolate,
+   struct tgsi_header *header );
+
+struct tgsi_full_declaration
+tgsi_default_full_declaration( void );
+
+GLuint
+tgsi_build_full_declaration(
+   const struct tgsi_full_declaration *full_decl,
+   struct tgsi_token *tokens,
+   struct tgsi_header *header,
+   GLuint maxsize );
+
+struct tgsi_declaration_range
+tgsi_build_declaration_range(
+   GLuint first,
+   GLuint last,
+   struct tgsi_declaration *declaration,
+   struct tgsi_header *header );
+
+struct tgsi_declaration_mask
+tgsi_build_declaration_mask(
+   GLuint mask,
+   struct tgsi_declaration *declaration,
+   struct tgsi_header *header );
+
+struct tgsi_declaration_interpolation
+tgsi_default_declaration_interpolation( void );
+
+struct tgsi_declaration_interpolation
+tgsi_build_declaration_interpolation(
+   GLuint interpolate,
+   struct tgsi_declaration *declaration,
+   struct tgsi_header *header );
+
+/*
+ * immediate
+ */
+
+struct tgsi_immediate
+tgsi_default_immediate( void );
+
+struct tgsi_immediate
+tgsi_build_immediate(
+   struct tgsi_header *header );
+
+struct tgsi_full_immediate
+tgsi_default_full_immediate( void );
+
+struct tgsi_immediate_float32
+tgsi_build_immediate_float32(
+   GLfloat value,
+   struct tgsi_immediate *immediate,
+   struct tgsi_header *header );
+
+GLuint
+tgsi_build_full_immediate(
+   const struct tgsi_full_immediate *full_imm,
+   struct tgsi_token *tokens,
+   struct tgsi_header *header,
+   GLuint maxsize );
+
+/*
+ * instruction
+ */
+
+struct tgsi_instruction
+tgsi_default_instruction( void );
+
+struct tgsi_instruction
+tgsi_build_instruction(
+   GLuint opcode,
+   GLuint saturate,
+   GLuint num_dst_regs,
+   GLuint num_src_regs,
+   struct tgsi_header *header );
+
+struct tgsi_full_instruction
+tgsi_default_full_instruction( void );
+
+GLuint
+tgsi_build_full_instruction(
+   const struct tgsi_full_instruction *full_inst,
+   struct tgsi_token *tokens,
+   struct tgsi_header *header,
+   GLuint maxsize );
+
+struct tgsi_instruction_ext_nv
+tgsi_default_instruction_ext_nv( void );
+
+GLuint
+tgsi_compare_instruction_ext_nv(
+   struct tgsi_instruction_ext_nv a,
+   struct tgsi_instruction_ext_nv b );
+
+struct tgsi_instruction_ext_nv
+tgsi_build_instruction_ext_nv(
+   GLuint precision,
+   GLuint cond_dst_index,
+   GLuint cond_flow_index,
+   GLuint cond_mask,
+   GLuint cond_swizzle_x,
+   GLuint cond_swizzle_y,
+   GLuint cond_swizzle_z,
+   GLuint cond_swizzle_w,
+   GLuint cond_dst_update,
+   GLuint cond_flow_update,
+   struct tgsi_token *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header );
+
+struct tgsi_instruction_ext_label
+tgsi_default_instruction_ext_label( void );
+
+GLuint
+tgsi_compare_instruction_ext_label(
+   struct tgsi_instruction_ext_label a,
+   struct tgsi_instruction_ext_label b );
+
+struct tgsi_instruction_ext_label
+tgsi_build_instruction_ext_label(
+   GLuint label,
+   GLuint target,
+   struct tgsi_token *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header );
+
+struct tgsi_instruction_ext_texture
+tgsi_default_instruction_ext_texture( void );
+
+GLuint
+tgsi_compare_instruction_ext_texture(
+   struct tgsi_instruction_ext_texture a,
+   struct tgsi_instruction_ext_texture b );
+
+struct tgsi_instruction_ext_texture
+tgsi_build_instruction_ext_texture(
+   GLuint texture,
+   struct tgsi_token *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header );
+
+struct tgsi_src_register
+tgsi_default_src_register( void );
+
+struct tgsi_src_register
+tgsi_build_src_register(
+   GLuint file,
+   GLuint swizzle_x,
+   GLuint swizzle_y,
+   GLuint swizzle_z,
+   GLuint swizzle_w,
+   GLuint negate,
+   GLuint indirect,
+   GLuint dimension,
+   GLint index,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header );
+
+struct tgsi_full_src_register
+tgsi_default_full_src_register( void );
+
+struct tgsi_src_register_ext_swz
+tgsi_default_src_register_ext_swz( void );
+
+GLuint
+tgsi_compare_src_register_ext_swz(
+   struct tgsi_src_register_ext_swz a,
+   struct tgsi_src_register_ext_swz b );
+
+struct tgsi_src_register_ext_swz
+tgsi_build_src_register_ext_swz(
+   GLuint ext_swizzle_x,
+   GLuint ext_swizzle_y,
+   GLuint ext_swizzle_z,
+   GLuint ext_swizzle_w,
+   GLuint negate_x,
+   GLuint negate_y,
+   GLuint negate_z,
+   GLuint negate_w,
+   GLuint ext_divide,
+   struct tgsi_token *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header );
+
+struct tgsi_src_register_ext_mod
+tgsi_default_src_register_ext_mod( void );
+
+GLuint
+tgsi_compare_src_register_ext_mod(
+   struct tgsi_src_register_ext_mod a,
+   struct tgsi_src_register_ext_mod b );
+
+struct tgsi_src_register_ext_mod
+tgsi_build_src_register_ext_mod(
+   GLuint complement,
+   GLuint bias,
+   GLuint scale_2x,
+   GLuint absolute,
+   GLuint negate,
+   struct tgsi_token *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header );
+
+struct tgsi_dimension
+tgsi_default_dimension( void );
+
+struct tgsi_dimension
+tgsi_build_dimension(
+   GLuint indirect,
+   GLuint index,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header );
+
+struct tgsi_dst_register
+tgsi_default_dst_register( void );
+
+struct tgsi_dst_register
+tgsi_build_dst_register(
+   GLuint file,
+   GLuint mask,
+   GLint index,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header );
+
+struct tgsi_full_dst_register
+tgsi_default_full_dst_register( void );
+
+struct tgsi_dst_register_ext_concode
+tgsi_default_dst_register_ext_concode( void );
+
+GLuint
+tgsi_compare_dst_register_ext_concode(
+   struct tgsi_dst_register_ext_concode a,
+   struct tgsi_dst_register_ext_concode b );
+
+struct tgsi_dst_register_ext_concode
+tgsi_build_dst_register_ext_concode(
+   GLuint cc,
+   GLuint swizzle_x,
+   GLuint swizzle_y,
+   GLuint swizzle_z,
+   GLuint swizzle_w,
+   GLint index,
+   struct tgsi_token *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header );
+
+struct tgsi_dst_register_ext_modulate
+tgsi_default_dst_register_ext_modulate( void );
+
+GLuint
+tgsi_compare_dst_register_ext_modulate(
+   struct tgsi_dst_register_ext_modulate a,
+   struct tgsi_dst_register_ext_modulate b );
+
+struct tgsi_dst_register_ext_modulate
+tgsi_build_dst_register_ext_modulate(
+   GLuint modulate,
+   struct tgsi_token *prev_token,
+   struct tgsi_instruction *instruction,
+   struct tgsi_header *header );
+
+#if defined __cplusplus
+} // extern "C"
+#endif // defined __cplusplus
+
+#endif // !defined TGSI_BUILD_H
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_core.h b/src/mesa/pipe/tgsi/core/tgsi_core.h
new file mode 100644 (file)
index 0000000..1f5f00a
--- /dev/null
@@ -0,0 +1,12 @@
+#if !defined TGSI_CORE_H
+#define TGSI_CORE_H
+
+#include "tgsi_token.h"
+#include "tgsi_parse.h"
+#include "tgsi_build.h"
+#include "tgsi_exec.h"
+#include "tgsi_dump.h"
+#include "tgsi_util.h"
+
+#endif // !defined TGSI_CORE_H
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_dump.c b/src/mesa/pipe/tgsi/core/tgsi_dump.c
new file mode 100644 (file)
index 0000000..33a898e
--- /dev/null
@@ -0,0 +1,881 @@
+#include "tgsi_platform.h"
+#include "tgsi_core.h"
+
+struct text_dump
+{
+    FILE *file;
+    GLuint tabs;
+};
+
+static void
+text_dump_write(
+   struct text_dump *dump,
+   const void *buffer,
+   GLuint size )
+{
+   fwrite( buffer, size, 1, dump->file );
+}
+
+static void
+text_dump_str(
+   struct text_dump *dump,
+   const char *str )
+{
+   GLuint i;
+   GLuint len = strlen( str );
+
+   for( i = 0; i < len; i++ ) {
+      text_dump_write( dump, &str[i], 1 );
+
+      if( str[i] == '\n' ) {
+         GLuint i;
+
+         for( i = 0; i < dump->tabs; i++ ) {
+            text_dump_write( dump, "    ", 4 );
+         }
+      }
+   }
+}
+
+static void
+text_dump_chr(
+   struct text_dump *dump,
+   const char chr )
+{
+   char str[2];
+
+   str[0] = chr;
+   str[1] = '\0';
+   text_dump_str( dump, str );
+}
+
+static void
+text_dump_uix(
+   struct text_dump *dump,
+   const GLuint ui)
+{
+   char str[36];
+
+   sprintf( str, "0x%x", ui );
+   text_dump_str( dump, str );
+}
+
+static void
+text_dump_uid(
+   struct text_dump *dump,
+   const GLuint ui )
+{
+   char str[16];
+
+   sprintf( str, "%u", ui );
+   text_dump_str( dump, str );
+}
+
+static void
+text_dump_sid(
+   struct text_dump *dump,
+   const GLint si )
+{
+   char str[16];
+
+   sprintf( str, "%d", si );
+   text_dump_str( dump, str );
+}
+
+static void
+text_dump_flt(
+   struct text_dump *dump,
+   const GLfloat f )
+{
+   char str[48];
+
+   sprintf( str, "%40.6f", f );
+   text_dump_str( dump, str );
+}
+
+static void
+text_dump_enum(
+   struct text_dump *dump,
+   const GLuint e,
+   const char **enums,
+   const GLuint enums_count )
+{
+   if( e >= enums_count ) {
+      text_dump_uid( dump, e );
+   }
+   else {
+      text_dump_str( dump, enums[e] );
+   }
+}
+
+static void
+text_dump_tab(
+   struct text_dump *dump )
+{
+   dump->tabs++;
+}
+
+static void
+text_dump_untab(
+   struct text_dump *dump )
+{
+   assert( dump->tabs > 0 );
+
+   --dump->tabs;
+}
+
+#define TXT(S)          text_dump_str( &dump, S )
+#define CHR(C)          text_dump_chr( &dump, C )
+#define UIX(I)          text_dump_uix( &dump, I )
+#define UID(I)          text_dump_uid( &dump, I )
+#define SID(I)          text_dump_sid( &dump, I )
+#define FLT(F)          text_dump_flt( &dump, F )
+#define TAB()           text_dump_tab( &dump )
+#define UNT()           text_dump_untab( &dump )
+#define ENM(E,ENUMS)    text_dump_enum( &dump, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) )
+
+static const char *TGSI_PROCESSOR_TYPES[] =
+{
+   "PROCESSOR_FRAGMENT",
+   "PROCESSOR_VERTEX"
+};
+
+static const char *TGSI_TOKEN_TYPES[] =
+{
+   "TOKEN_TYPE_DECLARATION",
+   "TOKEN_TYPE_IMMEDIATE",
+   "TOKEN_TYPE_INSTRUCTION"
+};
+
+static const char *TGSI_FILES[] =
+{
+   "FILE_NULL",
+   "FILE_CONSTANT",
+   "FILE_INPUT",
+   "FILE_OUTPUT",
+   "FILE_TEMPORARY",
+   "FILE_SAMPLER",
+   "FILE_ADDRESS",
+   "FILE_IMMEDIATE"
+};
+
+static const char *TGSI_DECLARES[] =
+{
+   "DECLARE_RANGE",
+   "DECLARE_MASK"
+};
+
+static const char *TGSI_INTERPOLATES[] =
+{
+   "INTERPOLATE_CONSTANT",
+   "INTERPOLATE_LINEAR",
+   "INTERPOLATE_PERSPECTIVE"
+};
+
+static const char *TGSI_IMMS[] =
+{
+   "IMM_FLOAT32"
+};
+
+static const char *TGSI_OPCODES[] =
+{
+   "OPCODE_ARL",
+   "OPCODE_MOV",
+   "OPCODE_LIT",
+   "OPCODE_RCP",
+   "OPCODE_RSQ",
+   "OPCODE_EXP",
+   "OPCODE_LOG",
+   "OPCODE_MUL",
+   "OPCODE_ADD",
+   "OPCODE_DP3",
+   "OPCODE_DP4",
+   "OPCODE_DST",
+   "OPCODE_MIN",
+   "OPCODE_MAX",
+   "OPCODE_SLT",
+   "OPCODE_SGE",
+   "OPCODE_MAD",
+   "OPCODE_SUB",
+   "OPCODE_LERP",
+   "OPCODE_CND",
+   "OPCODE_CND0",
+   "OPCODE_DOT2ADD",
+   "OPCODE_INDEX",
+   "OPCODE_NEGATE",
+   "OPCODE_FRAC",
+   "OPCODE_CLAMP",
+   "OPCODE_FLOOR",
+   "OPCODE_ROUND",
+   "OPCODE_EXPBASE2",
+   "OPCODE_LOGBASE2",
+   "OPCODE_POWER",
+   "OPCODE_CROSSPRODUCT",
+   "OPCODE_MULTIPLYMATRIX",
+   "OPCODE_ABS",
+   "OPCODE_RCC",
+   "OPCODE_DPH",
+   "OPCODE_COS",
+   "OPCODE_DDX",
+   "OPCODE_DDY",
+   "OPCODE_KIL",
+   "OPCODE_PK2H",
+   "OPCODE_PK2US",
+   "OPCODE_PK4B",
+   "OPCODE_PK4UB",
+   "OPCODE_RFL",
+   "OPCODE_SEQ",
+   "OPCODE_SFL",
+   "OPCODE_SGT",
+   "OPCODE_SIN",
+   "OPCODE_SLE",
+   "OPCODE_SNE",
+   "OPCODE_STR",
+   "OPCODE_TEX",
+   "OPCODE_TXD",
+   "OPCODE_UP2H",
+   "OPCODE_UP2US",
+   "OPCODE_UP4B",
+   "OPCODE_UP4UB",
+   "OPCODE_X2D",
+   "OPCODE_ARA",
+   "OPCODE_ARR",
+   "OPCODE_BRA",
+   "OPCODE_CAL",
+   "OPCODE_RET",
+   "OPCODE_SSG",
+   "OPCODE_CMP",
+   "OPCODE_SCS",
+   "OPCODE_TXB",
+   "OPCODE_NRM",
+   "OPCODE_DIV",
+   "OPCODE_DP2",
+   "OPCODE_TXL",
+   "OPCODE_BRK",
+   "OPCODE_IF",
+   "OPCODE_LOOP",
+   "OPCODE_REP",
+   "OPCODE_ELSE",
+   "OPCODE_ENDIF",
+   "OPCODE_ENDLOOP",
+   "OPCODE_ENDREP",
+   "OPCODE_PUSHA",
+   "OPCODE_POPA",
+   "OPCODE_CEIL",
+   "OPCODE_I2F",
+   "OPCODE_NOT",
+   "OPCODE_TRUNC",
+   "OPCODE_SHL",
+   "OPCODE_SHR",
+   "OPCODE_AND",
+   "OPCODE_OR",
+   "OPCODE_MOD",
+   "OPCODE_XOR",
+   "OPCODE_SAD",
+   "OPCODE_TXF",
+   "OPCODE_TXQ",
+   "OPCODE_CONT",
+   "OPCODE_EMIT",
+   "OPCODE_ENDPRIM"
+};
+
+static const char *TGSI_SATS[] =
+{
+   "SAT_NONE",
+   "SAT_ZERO_ONE",
+   "SAT_MINUS_PLUS_ONE"
+};
+
+static const char *TGSI_INSTRUCTION_EXTS[] =
+{
+   "INSTRUCTION_EXT_TYPE_NV",
+   "INSTRUCTION_EXT_TYPE_LABEL",
+   "INSTRUCTION_EXT_TYPE_TEXTURE"
+};
+
+static const char *TGSI_PRECISIONS[] =
+{
+   "PRECISION_DEFAULT",
+   "TGSI_PRECISION_FLOAT32",
+   "TGSI_PRECISION_FLOAT16",
+   "TGSI_PRECISION_FIXED12"
+};
+
+static const char *TGSI_CCS[] =
+{
+   "CC_GT",
+   "CC_EQ",
+   "CC_LT",
+   "CC_UN",
+   "CC_GE",
+   "CC_LE",
+   "CC_NE",
+   "CC_TR",
+   "CC_FL"
+};
+
+static const char *TGSI_SWIZZLES[] =
+{
+   "SWIZZLE_X",
+   "SWIZZLE_Y",
+   "SWIZZLE_Z",
+   "SWIZZLE_W"
+};
+
+static const char *TGSI_TEXTURES[] =
+{
+   "TEXTURE_UNKNOWN",
+   "TEXTURE_1D",
+   "TEXTURE_2D",
+   "TEXTURE_3D",
+   "TEXTURE_CUBE",
+   "TEXTURE_RECT",
+   "TEXTURE_SHADOW1D",
+   "TEXTURE_SHADOW2D",
+   "TEXTURE_SHADOWRECT"
+};
+
+static const char *TGSI_SRC_REGISTER_EXTS[] =
+{
+   "SRC_REGISTER_EXT_TYPE_SWZ",
+   "SRC_REGISTER_EXT_TYPE_MOD"
+};
+
+static const char *TGSI_EXTSWIZZLES[] =
+{
+   "EXTSWIZZLE_X",
+   "EXTSWIZZLE_Y",
+   "EXTSWIZZLE_Z",
+   "EXTSWIZZLE_W",
+   "EXTSWIZZLE_ZERO",
+   "EXTSWIZZLE_ONE"
+};
+
+static const char *TGSI_WRITEMASKS[] =
+{
+   "0",
+   "WRITEMASK_X",
+   "WRITEMASK_Y",
+   "WRITEMASK_XY",
+   "WRITEMASK_Z",
+   "WRITEMASK_XZ",
+   "WRITEMASK_YZ",
+   "WRITEMASK_XYZ",
+   "WRITEMASK_W",
+   "WRITEMASK_XW",
+   "WRITEMASK_YW",
+   "WRITEMASK_XYW",
+   "WRITEMASK_ZW",
+   "WRITEMASK_XZW",
+   "WRITEMASK_YZW",
+   "WRITEMASK_XYZW"
+};
+
+static const char *TGSI_DST_REGISTER_EXTS[] =
+{
+   "DST_REGISTER_EXT_TYPE_CONDCODE",
+   "DST_REGISTER_EXT_TYPE_MODULATE"
+};
+
+static const char *TGSI_MODULATES[] =
+{
+   "MODULATE_1X",
+   "MODULATE_2X",
+   "MODULATE_4X",
+   "MODULATE_8X",
+   "MODULATE_HALF",
+   "MODULATE_QUARTER",
+   "MODULATE_EIGHTH"
+};
+
+void
+tgsi_dump(
+   const struct tgsi_token *tokens,
+   GLuint flags )
+{
+   struct text_dump dump;
+   struct tgsi_parse_context parse;
+   struct tgsi_full_instruction fi;
+   struct tgsi_full_declaration fd;
+   GLuint ignored = !(flags & TGSI_DUMP_NO_IGNORED);
+   GLuint deflt = !(flags & TGSI_DUMP_NO_DEFAULT);
+
+   {
+#if 0
+      static GLuint counter = 0;
+      char buffer[64];
+
+      sprintf( buffer, "tgsi-dump-%.4u.txt", counter++ );
+      dump.file = fopen( buffer, "wt" );
+#else
+      dump.file = stderr;
+      dump.tabs = 0;
+#endif
+   }
+
+   /* sanity check */
+   assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0);
+
+   tgsi_parse_init( &parse, tokens );
+
+   TXT( "tgsi-dump begin" );
+
+   CHR( '\n' );
+   TXT( "\nMajorVersion: " );
+   UID( parse.FullVersion.Version.MajorVersion );
+   TXT( "\nMinorVersion: " );
+   UID( parse.FullVersion.Version.MinorVersion );
+
+   CHR( '\n' );
+   TXT( "\nHeaderSize: " );
+   UID( parse.FullHeader.Header.HeaderSize );
+   TXT( "\nBodySize  : " );
+   UID( parse.FullHeader.Header.BodySize );
+   TXT( "\nProcessor : " );
+   ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES );
+
+   fi = tgsi_default_full_instruction();
+   fd = tgsi_default_full_declaration();
+
+   while( !tgsi_parse_end_of_tokens( &parse ) ) {
+      GLuint i;
+
+      tgsi_parse_token( &parse );
+
+      CHR( '\n' );
+      TXT( "\nType       : " );
+      ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES );
+      if( ignored ) {
+         TXT( "\nSize       : " );
+         UID( parse.FullToken.Token.Size );
+         if( deflt || parse.FullToken.Token.Extended ) {
+            TXT( "\nExtended   : " );
+            UID( parse.FullToken.Token.Extended );
+         }
+      }
+
+      switch( parse.FullToken.Token.Type ) {
+      case TGSI_TOKEN_TYPE_DECLARATION:
+         {
+            struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration;
+
+            TXT( "\nFile       : " );
+            ENM( decl->Declaration.File, TGSI_FILES );
+            TXT( "\nDeclare    : " );
+            ENM( decl->Declaration.Declare, TGSI_DECLARES );
+            if( deflt || fd.Declaration.Interpolate != decl->Declaration.Interpolate ) {
+               TXT( "\nInterpolate: " );
+               UID( decl->Declaration.Interpolate );
+            }
+            if( ignored ) {
+               TXT( "\nPadding    : " );
+               UIX( decl->Declaration.Padding );
+            }
+
+            CHR( '\n' );
+            switch( decl->Declaration.Declare ) {
+            case TGSI_DECLARE_RANGE:
+               TXT( "\nFirst: " );
+               UID( decl->u.DeclarationRange.First );
+               TXT( "\nLast : " );
+               UID( decl->u.DeclarationRange.Last );
+               break;
+
+            case TGSI_DECLARE_MASK:
+               TXT( "\nMask: " );
+               UIX( decl->u.DeclarationMask.Mask );
+               break;
+
+            default:
+               assert( 0 );
+            }
+
+            if( decl->Declaration.Interpolate ) {
+               CHR( '\n' );
+               TXT( "\nInterpolate: " );
+               ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES );
+               if( ignored ) {
+                  TXT( "\nPadding    : " );
+                  UIX( decl->Interpolation.Padding );
+               }
+            }
+         }
+         break;
+
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+         TXT( "\nDataType   : " );
+         ENM( parse.FullToken.FullImmediate.Immediate.DataType, TGSI_IMMS );
+         if( ignored ) {
+            TXT( "\nPadding    : " );
+            UIX( parse.FullToken.FullImmediate.Immediate.Padding );
+         }
+
+         for( i = 0; i < parse.FullToken.FullImmediate.Immediate.Size - 1; i++ ) {
+            CHR( '\n' );
+            switch( parse.FullToken.FullImmediate.Immediate.DataType ) {
+            case TGSI_IMM_FLOAT32:
+               TXT( "\nFloat: " );
+               FLT( parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float );
+               break;
+
+            default:
+               assert( 0 );
+            }
+         }
+         break;
+
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+         {
+            struct tgsi_full_instruction *inst = &parse.FullToken.FullInstruction;
+
+            TXT( "\nOpcode     : " );
+            ENM( inst->Instruction.Opcode, TGSI_OPCODES );
+            if( deflt || fi.Instruction.Saturate != inst->Instruction.Saturate ) {
+               TXT( "\nSaturate   : " );
+               ENM( inst->Instruction.Saturate, TGSI_SATS );
+            }
+            if( deflt || fi.Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) {
+               TXT( "\nNumDstRegs : " );
+               UID( inst->Instruction.NumDstRegs );
+            }
+            if( deflt || fi.Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) {
+               TXT( "\nNumSrcRegs : " );
+               UID( inst->Instruction.NumSrcRegs );
+            }
+            if( ignored ) {
+               TXT( "\nPadding    : " );
+               UIX( inst->Instruction.Padding );
+            }
+
+            if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi.InstructionExtNv)) {
+               CHR( '\n' );
+               TXT( "\nType          : " );
+               ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS );
+               if( deflt || fi.InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) {
+                  TXT( "\nPrecision     : " );
+                  ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS );
+               }
+               if( deflt || fi.InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) {
+                  TXT( "\nCondDstIndex  : " );
+                  UID( inst->InstructionExtNv.CondDstIndex );
+               }
+               if( deflt || fi.InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) {
+                  TXT( "\nCondFlowIndex : " );
+                  UID( inst->InstructionExtNv.CondFlowIndex );
+               }
+               if( deflt || fi.InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) {
+                  TXT( "\nCondMask      : " );
+                  ENM( inst->InstructionExtNv.CondMask, TGSI_CCS );
+               }
+               if( deflt || fi.InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) {
+                  TXT( "\nCondSwizzleX  : " );
+                  ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES );
+               }
+               if( deflt || fi.InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) {
+                  TXT( "\nCondSwizzleY  : " );
+                  ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES );
+               }
+               if( deflt || fi.InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) {
+                  TXT( "\nCondSwizzleZ  : " );
+                  ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES );
+               }
+               if( deflt || fi.InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) {
+                  TXT( "\nCondSwizzleW  : " );
+                  ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES );
+               }
+               if( deflt || fi.InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) {
+                  TXT( "\nCondDstUpdate : " );
+                  UID( inst->InstructionExtNv.CondDstUpdate );
+               }
+               if( deflt || fi.InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) {
+                  TXT( "\nCondFlowEnable: " );
+                  UID( inst->InstructionExtNv.CondFlowEnable );
+               }
+               if( ignored ) {
+                  TXT( "\nPadding       : " );
+                  UIX( inst->InstructionExtNv.Padding );
+                  if( deflt || fi.InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) {
+                     TXT( "\nExtended      : " );
+                     UID( inst->InstructionExtNv.Extended );
+                  }
+               }
+            }
+
+            if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi.InstructionExtLabel ) ) {
+               CHR( '\n' );
+               TXT( "\nType    : " );
+               ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS );
+               if( deflt || fi.InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) {
+                  TXT( "\nLabel   : " );
+                  UID( inst->InstructionExtLabel.Label );
+               }
+               if( deflt || fi.InstructionExtLabel.Target != inst->InstructionExtLabel.Target ) {
+                  TXT( "\nTarget  : " );
+                  UID( inst->InstructionExtLabel.Target );
+               }
+               if( ignored ) {
+                  TXT( "\nPadding : " );
+                  UIX( inst->InstructionExtLabel.Padding );
+                  if( deflt || fi.InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) {
+                     TXT( "\nExtended: " );
+                     UID( inst->InstructionExtLabel.Extended );
+                  }
+               }
+            }
+
+            if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi.InstructionExtTexture ) ) {
+               CHR( '\n' );
+               TXT( "\nType    : " );
+               ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS );
+               if( deflt || fi.InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) {
+                  TXT( "\nTexture : " );
+                  ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES );
+               }
+               if( ignored ) {
+                  TXT( "\nPadding : " );
+                  UIX( inst->InstructionExtTexture.Padding );
+                  if( deflt || fi.InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) {
+                     TXT( "\nExtended: " );
+                     UID( inst->InstructionExtTexture.Extended );
+                  }
+               }
+            }
+
+            for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
+               struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
+               struct tgsi_full_dst_register *fd = &fi.FullDstRegisters[i];
+
+               CHR( '\n' );
+               TXT( "\nFile     : " );
+               ENM( dst->DstRegister.File, TGSI_FILES );
+               if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) {
+                  TXT( "\nWriteMask: " );
+                  ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS );
+               }
+               if( ignored ) {
+                  if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) {
+                     TXT( "\nIndirect : " );
+                     UID( dst->DstRegister.Indirect );
+                  }
+                  if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) {
+                     TXT( "\nDimension: " );
+                     UID( dst->DstRegister.Dimension );
+                  }
+               }
+               if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) {
+                  TXT( "\nIndex    : " );
+                  SID( dst->DstRegister.Index );
+               }
+               if( ignored ) {
+                  TXT( "\nPadding  : " );
+                  UIX( dst->DstRegister.Padding );
+                  if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) {
+                     TXT( "\nExtended : " );
+                     UID( dst->DstRegister.Extended );
+                  }
+               }
+
+               if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) {
+                  CHR( '\n' );
+                  TXT( "\nType        : " );
+                  ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS );
+                  if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) {
+                     TXT( "\nCondMask    : " );
+                     ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS );
+                  }
+                  if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) {
+                     TXT( "\nCondSwizzleX: " );
+                     ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES );
+                  }
+                  if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) {
+                     TXT( "\nCondSwizzleY: " );
+                     ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES );
+                  }
+                  if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) {
+                     TXT( "\nCondSwizzleZ: " );
+                     ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES );
+                  }
+                  if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) {
+                     TXT( "\nCondSwizzleW: " );
+                     ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES );
+                  }
+                  if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) {
+                     TXT( "\nCondSrcIndex: " );
+                     UID( dst->DstRegisterExtConcode.CondSrcIndex );
+                  }
+                  if( ignored ) {
+                     TXT( "\nPadding     : " );
+                     UIX( dst->DstRegisterExtConcode.Padding );
+                     if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) {
+                        TXT( "\nExtended    : " );
+                        UID( dst->DstRegisterExtConcode.Extended );
+                     }
+                  }
+               }
+
+               if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) {
+                  CHR( '\n' );
+                  TXT( "\nType    : " );
+                  ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS );
+                  if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) {
+                     TXT( "\nModulate: " );
+                     ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES );
+                  }
+                  if( ignored ) {
+                     TXT( "\nPadding : " );
+                     UIX( dst->DstRegisterExtModulate.Padding );
+                     if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) {
+                        TXT( "\nExtended: " );
+                        UID( dst->DstRegisterExtModulate.Extended );
+                     }
+                  }
+               }
+            }
+
+            for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
+               struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
+               struct tgsi_full_src_register *fs = &fi.FullSrcRegisters[i];
+
+               CHR( '\n' );
+               TXT( "\nFile     : ");
+               ENM( src->SrcRegister.File, TGSI_FILES );
+               if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) {
+                  TXT( "\nSwizzleX : " );
+                  ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES );
+               }
+               if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) {
+                  TXT( "\nSwizzleY : " );
+                  ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES );
+               }
+               if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) {
+                  TXT( "\nSwizzleZ : " );
+                  ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES );
+               }
+               if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) {
+                  TXT( "\nSwizzleW : " );
+                  ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES );
+               }
+               if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) {
+                  TXT( "\nNegate   : " );
+                  UID( src->SrcRegister.Negate );
+               }
+               if( ignored ) {
+                  if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) {
+                     TXT( "\nIndirect : " );
+                     UID( src->SrcRegister.Indirect );
+                  }
+                  if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) {
+                     TXT( "\nDimension: " );
+                     UID( src->SrcRegister.Dimension );
+                  }
+               }
+               if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) {
+                  TXT( "\nIndex    : " );
+                  SID( src->SrcRegister.Index );
+               }
+               if( ignored ) {
+                  if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) {
+                     TXT( "\nExtended : " );
+                     UID( src->SrcRegister.Extended );
+                  }
+               }
+
+               if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) {
+                  CHR( '\n' );
+                  TXT( "\nType       : " );
+                  ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS );
+                  if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) {
+                     TXT( "\nExtSwizzleX: " );
+                     ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES );
+                  }
+                  if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) {
+                     TXT( "\nExtSwizzleY: " );
+                     ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES );
+                  }
+                  if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) {
+                     TXT( "\nExtSwizzleZ: " );
+                     ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES );
+                  }
+                  if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) {
+                     TXT( "\nExtSwizzleW: " );
+                     ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES );
+                  }
+                  if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) {
+                     TXT( "\nNegateX   : " );
+                     UID( src->SrcRegisterExtSwz.NegateX );
+                  }
+                  if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) {
+                     TXT( "\nNegateY   : " );
+                     UID( src->SrcRegisterExtSwz.NegateY );
+                  }
+                  if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) {
+                     TXT( "\nNegateZ   : " );
+                     UID( src->SrcRegisterExtSwz.NegateZ );
+                  }
+                  if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) {
+                     TXT( "\nNegateW   : " );
+                     UID( src->SrcRegisterExtSwz.NegateW );
+                  }
+                  if( deflt || fs->SrcRegisterExtSwz.ExtDivide != src->SrcRegisterExtSwz.ExtDivide ) {
+                     TXT( "\nExtDivide  : " );
+                     ENM( src->SrcRegisterExtSwz.ExtDivide, TGSI_EXTSWIZZLES );
+                  }
+                  if( ignored ) {
+                     TXT( "\nPadding   : " );
+                     UIX( src->SrcRegisterExtSwz.Padding );
+                     if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) {
+                        TXT( "\nExtended   : " );
+                        UID( src->SrcRegisterExtSwz.Extended );
+                     }
+                  }
+               }
+
+               if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) {
+                  CHR( '\n' );
+                  TXT( "\nType     : " );
+                  ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS );
+                  if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) {
+                     TXT( "\nComplement: " );
+                     UID( src->SrcRegisterExtMod.Complement );
+                  }
+                  if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) {
+                     TXT( "\nBias     : " );
+                     UID( src->SrcRegisterExtMod.Bias );
+                  }
+                  if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) {
+                     TXT( "\nScale2X   : " );
+                     UID( src->SrcRegisterExtMod.Scale2X );
+                  }
+                  if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) {
+                     TXT( "\nAbsolute  : " );
+                     UID( src->SrcRegisterExtMod.Absolute );
+                  }
+                  if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) {
+                     TXT( "\nNegate   : " );
+                     UID( src->SrcRegisterExtMod.Negate );
+                  }
+                  if( ignored ) {
+                     TXT( "\nPadding   : " );
+                     UIX( src->SrcRegisterExtMod.Padding );
+                     if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) {
+                        TXT( "\nExtended  : " );
+                        UID( src->SrcRegisterExtMod.Extended );
+                     }
+                  }
+               }
+            }
+         }
+         break;
+
+      default:
+         assert( 0 );
+      }
+   }
+
+   TXT( "\ntgsi-dump end\n" );
+
+   tgsi_parse_free( &parse );
+
+   fclose( dump.file );
+}
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_dump.h b/src/mesa/pipe/tgsi/core/tgsi_dump.h
new file mode 100644 (file)
index 0000000..dc34a84
--- /dev/null
@@ -0,0 +1,22 @@
+#if !defined TGSI_DUMP_H
+#define TGSI_DUMP_H
+
+#if defined __cplusplus
+extern "C" {
+#endif // defined __cplusplus
+
+#define TGSI_DUMP_VERBOSE       0
+#define TGSI_DUMP_NO_IGNORED    1
+#define TGSI_DUMP_NO_DEFAULT    2
+
+void
+tgsi_dump(
+   const struct tgsi_token *tokens,
+   GLuint flags );
+
+#if defined __cplusplus
+} // extern "C"
+#endif // defined __cplusplus
+
+#endif // !defined TGSI_DUMP_H
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_exec.c b/src/mesa/pipe/tgsi/core/tgsi_exec.c
new file mode 100644 (file)
index 0000000..6aaaef9
--- /dev/null
@@ -0,0 +1,2249 @@
+#include "tgsi_platform.h"
+#include "tgsi_core.h"
+
+#define MESA 1
+#if MESA
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/colormac.h"
+#include "swrast/swrast.h"
+#include "swrast/s_context.h"
+#endif
+
+#define TILE_BOTTOM_LEFT  0
+#define TILE_BOTTOM_RIGHT 1
+#define TILE_TOP_LEFT     2
+#define TILE_TOP_RIGHT    3
+
+#define TEMP_0_I           TGSI_EXEC_TEMP_00000000_I
+#define TEMP_0_C           TGSI_EXEC_TEMP_00000000_C
+#define TEMP_7F_I          TGSI_EXEC_TEMP_7FFFFFFF_I
+#define TEMP_7F_C          TGSI_EXEC_TEMP_7FFFFFFF_C
+#define TEMP_80_I          TGSI_EXEC_TEMP_80000000_I
+#define TEMP_80_C          TGSI_EXEC_TEMP_80000000_C
+#define TEMP_FF_I          TGSI_EXEC_TEMP_FFFFFFFF_I
+#define TEMP_FF_C          TGSI_EXEC_TEMP_FFFFFFFF_C
+#define TEMP_1_I           TGSI_EXEC_TEMP_ONE_I
+#define TEMP_1_C           TGSI_EXEC_TEMP_ONE_C
+#define TEMP_2_I           TGSI_EXEC_TEMP_TWO_I
+#define TEMP_2_C           TGSI_EXEC_TEMP_TWO_C
+#define TEMP_128_I         TGSI_EXEC_TEMP_128_I
+#define TEMP_128_C         TGSI_EXEC_TEMP_128_C
+#define TEMP_M128_I        TGSI_EXEC_TEMP_MINUS_128_I
+#define TEMP_M128_C        TGSI_EXEC_TEMP_MINUS_128_C
+#define TEMP_KILMASK_I     TGSI_EXEC_TEMP_KILMASK_I
+#define TEMP_KILMASK_C     TGSI_EXEC_TEMP_KILMASK_C
+#define TEMP_OUTPUT_I      TGSI_EXEC_TEMP_OUTPUT_I
+#define TEMP_OUTPUT_C      TGSI_EXEC_TEMP_OUTPUT_C
+#define TEMP_PRIMITIVE_I   TGSI_EXEC_TEMP_PRIMITIVE_I
+#define TEMP_PRIMITIVE_C   TGSI_EXEC_TEMP_PRIMITIVE_C
+#define TEMP_R0            TGSI_EXEC_TEMP_R0
+
+#define FOR_EACH_CHANNEL(CHAN)\
+   for (CHAN = 0; CHAN < 4; CHAN++)
+
+#define IS_CHANNEL_ENABLED(INST, CHAN)\
+   ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN)))
+
+#define IS_CHANNEL_ENABLED2(INST, CHAN)\
+   ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN)))
+
+#define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\
+   FOR_EACH_CHANNEL( CHAN )\
+      if (IS_CHANNEL_ENABLED( INST, CHAN ))
+
+#define FOR_EACH_ENABLED_CHANNEL2(INST, CHAN)\
+   FOR_EACH_CHANNEL( CHAN )\
+      if (IS_CHANNEL_ENABLED2( INST, CHAN ))
+
+#define CHAN_X  0
+#define CHAN_Y  1
+#define CHAN_Z  2
+#define CHAN_W  3
+
+void
+tgsi_exec_machine_init(
+   struct tgsi_exec_machine *mach,
+   struct tgsi_token *tokens )
+{
+   GLuint i, k;
+   struct tgsi_parse_context parse;
+
+   mach->Tokens = tokens;
+
+   k = tgsi_parse_init (&parse, mach->Tokens);
+   if (k != TGSI_PARSE_OK) {
+      printf("Problem parsing!\n");
+      return;
+   }
+
+   mach->Processor = parse.FullHeader.Processor.Processor;
+   tgsi_parse_free (&parse);
+
+   mach->Temps = (struct tgsi_exec_vector *) tgsi_align_128bit( mach->_Temps);
+   mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS];
+
+#if XXX_SSE
+    tgsi_emit_sse (tokens,
+                   &mach->Function);
+#endif
+
+   /* Setup constants. */
+   for( i = 0; i < 4; i++ ) {
+      mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].u[i] = 0x00000000;
+      mach->Temps[TEMP_7F_I].xyzw[TEMP_7F_C].u[i] = 0x7FFFFFFF;
+      mach->Temps[TEMP_80_I].xyzw[TEMP_80_C].u[i] = 0x80000000;
+      mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].u[i] = 0xFFFFFFFF;
+      mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].f[i] = 1.0f;
+      mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].f[i] = 2.0f;
+      mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].f[i] = 128.0f;
+      mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].f[i] = -128.0f;
+   }
+}
+
+void
+tgsi_exec_prepare(
+   struct tgsi_exec_machine *mach,
+   struct tgsi_exec_labels *labels )
+{
+   struct tgsi_parse_context parse;
+   GLuint k;
+
+   mach->ImmLimit = 0;
+   labels->count = 0;
+
+   k = tgsi_parse_init( &parse, mach->Tokens );
+   if (k != TGSI_PARSE_OK) {
+      printf("Problem parsing!\n");
+      return;
+   }
+
+   while( !tgsi_parse_end_of_tokens( &parse ) ) {
+      GLuint pointer = parse.Position;
+      GLuint i;
+      tgsi_parse_token( &parse );
+      switch( parse.FullToken.Token.Type ) {
+      case TGSI_TOKEN_TYPE_DECLARATION:
+         break;
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+         assert( (parse.FullToken.FullImmediate.Immediate.Size - 1) % 4 == 0 );
+         assert( mach->ImmLimit + (parse.FullToken.FullImmediate.Immediate.Size - 1) / 4 <= 256 );
+         for( i = 0; i < parse.FullToken.FullImmediate.Immediate.Size - 1; i++ ) {
+            mach->Imms[mach->ImmLimit + i / 4][i % 4] = parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float;
+         }
+         mach->ImmLimit += (parse.FullToken.FullImmediate.Immediate.Size - 1) / 4;
+         break;
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+         if( parse.FullToken.FullInstruction.InstructionExtLabel.Label &&
+             parse.FullToken.FullInstruction.InstructionExtLabel.Target ) {
+            assert( labels->count < 128 );
+            labels->labels[labels->count][0] = parse.FullToken.FullInstruction.InstructionExtLabel.Label;
+            labels->labels[labels->count][1] = pointer;
+            labels->count++;
+         }
+         break;
+      default:
+         assert( 0 );
+      }
+   }
+   tgsi_parse_free (&parse);
+}
+
+void
+tgsi_exec_machine_run(
+   struct tgsi_exec_machine *mach )
+{
+   struct tgsi_exec_labels labels;
+
+   tgsi_exec_prepare( mach, &labels );
+   tgsi_exec_machine_run2( mach, &labels );
+}
+
+static void
+micro_abs(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) fabs( (GLdouble) src->f[0] );
+   dst->f[1] = (GLfloat) fabs( (GLdouble) src->f[1] );
+   dst->f[2] = (GLfloat) fabs( (GLdouble) src->f[2] );
+   dst->f[3] = (GLfloat) fabs( (GLdouble) src->f[3] );
+}
+
+static void
+micro_add(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->f[0] = src0->f[0] + src1->f[0];
+   dst->f[1] = src0->f[1] + src1->f[1];
+   dst->f[2] = src0->f[2] + src1->f[2];
+   dst->f[3] = src0->f[3] + src1->f[3];
+}
+
+static void
+micro_iadd(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->i[0] = src0->i[0] + src1->i[0];
+   dst->i[1] = src0->i[1] + src1->i[1];
+   dst->i[2] = src0->i[2] + src1->i[2];
+   dst->i[3] = src0->i[3] + src1->i[3];
+}
+
+static void
+micro_and(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->u[0] = src0->u[0] & src1->u[0];
+   dst->u[1] = src0->u[1] & src1->u[1];
+   dst->u[2] = src0->u[2] & src1->u[2];
+   dst->u[3] = src0->u[3] & src1->u[3];
+}
+
+static void
+micro_ceil(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) ceil( (GLdouble) src->f[0] );
+   dst->f[1] = (GLfloat) ceil( (GLdouble) src->f[1] );
+   dst->f[2] = (GLfloat) ceil( (GLdouble) src->f[2] );
+   dst->f[3] = (GLfloat) ceil( (GLdouble) src->f[3] );
+}
+
+static void
+micro_cos(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) cos( (GLdouble) src->f[0] );
+   dst->f[1] = (GLfloat) cos( (GLdouble) src->f[1] );
+   dst->f[2] = (GLfloat) cos( (GLdouble) src->f[2] );
+   dst->f[3] = (GLfloat) cos( (GLdouble) src->f[3] );
+}
+
+static void
+micro_ddx(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] =
+   dst->f[1] =
+   dst->f[2] =
+   dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT];
+}
+
+static void
+micro_ddy(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] =
+   dst->f[1] =
+   dst->f[2] =
+   dst->f[3] = src->f[TILE_TOP_LEFT] - src->f[TILE_BOTTOM_LEFT];
+}
+
+static void
+micro_div(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->f[0] = src0->f[0] / src1->f[0];
+   dst->f[1] = src0->f[1] / src1->f[1];
+   dst->f[2] = src0->f[2] / src1->f[2];
+   dst->f[3] = src0->f[3] / src1->f[3];
+}
+
+static void
+micro_udiv(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->u[0] = src0->u[0] / src1->u[0];
+   dst->u[1] = src0->u[1] / src1->u[1];
+   dst->u[2] = src0->u[2] / src1->u[2];
+   dst->u[3] = src0->u[3] / src1->u[3];
+}
+
+static void
+micro_eq(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1,
+   const union tgsi_exec_channel *src2,
+   const union tgsi_exec_channel *src3 )
+{
+   dst->f[0] = src0->f[0] == src1->f[0] ? src2->f[0] : src3->f[0];
+   dst->f[1] = src0->f[1] == src1->f[1] ? src2->f[1] : src3->f[1];
+   dst->f[2] = src0->f[2] == src1->f[2] ? src2->f[2] : src3->f[2];
+   dst->f[3] = src0->f[3] == src1->f[3] ? src2->f[3] : src3->f[3];
+}
+
+static void
+micro_ieq(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1,
+   const union tgsi_exec_channel *src2,
+   const union tgsi_exec_channel *src3 )
+{
+   dst->i[0] = src0->i[0] == src1->i[0] ? src2->i[0] : src3->i[0];
+   dst->i[1] = src0->i[1] == src1->i[1] ? src2->i[1] : src3->i[1];
+   dst->i[2] = src0->i[2] == src1->i[2] ? src2->i[2] : src3->i[2];
+   dst->i[3] = src0->i[3] == src1->i[3] ? src2->i[3] : src3->i[3];
+}
+
+static void
+micro_exp2(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) pow( 2.0, (GLdouble) src->f[0] );
+   dst->f[1] = (GLfloat) pow( 2.0, (GLdouble) src->f[1] );
+   dst->f[2] = (GLfloat) pow( 2.0, (GLdouble) src->f[2] );
+   dst->f[3] = (GLfloat) pow( 2.0, (GLdouble) src->f[3] );
+}
+
+static void
+micro_f2it(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->i[0] = (GLint) src->f[0];
+   dst->i[1] = (GLint) src->f[1];
+   dst->i[2] = (GLint) src->f[2];
+   dst->i[3] = (GLint) src->f[3];
+}
+
+static void
+micro_f2ut(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->u[0] = (GLuint) src->f[0];
+   dst->u[1] = (GLuint) src->f[1];
+   dst->u[2] = (GLuint) src->f[2];
+   dst->u[3] = (GLuint) src->f[3];
+}
+
+static void
+micro_flr(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) floor( (GLdouble) src->f[0] );
+   dst->f[1] = (GLfloat) floor( (GLdouble) src->f[1] );
+   dst->f[2] = (GLfloat) floor( (GLdouble) src->f[2] );
+   dst->f[3] = (GLfloat) floor( (GLdouble) src->f[3] );
+}
+
+static void
+micro_frc(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = src->f[0] - (GLfloat) floor( (GLdouble) src->f[0] );
+   dst->f[1] = src->f[1] - (GLfloat) floor( (GLdouble) src->f[1] );
+   dst->f[2] = src->f[2] - (GLfloat) floor( (GLdouble) src->f[2] );
+   dst->f[3] = src->f[3] - (GLfloat) floor( (GLdouble) src->f[3] );
+}
+
+static void
+micro_i2f(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) src->i[0];
+   dst->f[1] = (GLfloat) src->i[1];
+   dst->f[2] = (GLfloat) src->i[2];
+   dst->f[3] = (GLfloat) src->i[3];
+}
+
+static void
+micro_lg2(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) log( (GLdouble) src->f[0] ) * 1.442695f;
+   dst->f[1] = (GLfloat) log( (GLdouble) src->f[1] ) * 1.442695f;
+   dst->f[2] = (GLfloat) log( (GLdouble) src->f[2] ) * 1.442695f;
+   dst->f[3] = (GLfloat) log( (GLdouble) src->f[3] ) * 1.442695f;
+}
+
+static void
+micro_lt(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1,
+   const union tgsi_exec_channel *src2,
+   const union tgsi_exec_channel *src3 )
+{
+   dst->f[0] = src0->f[0] < src1->f[0] ? src2->f[0] : src3->f[0];
+   dst->f[1] = src0->f[1] < src1->f[1] ? src2->f[1] : src3->f[1];
+   dst->f[2] = src0->f[2] < src1->f[2] ? src2->f[2] : src3->f[2];
+   dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3];
+}
+
+static void
+micro_ilt(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1,
+   const union tgsi_exec_channel *src2,
+   const union tgsi_exec_channel *src3 )
+{
+   dst->i[0] = src0->i[0] < src1->i[0] ? src2->i[0] : src3->i[0];
+   dst->i[1] = src0->i[1] < src1->i[1] ? src2->i[1] : src3->i[1];
+   dst->i[2] = src0->i[2] < src1->i[2] ? src2->i[2] : src3->i[2];
+   dst->i[3] = src0->i[3] < src1->i[3] ? src2->i[3] : src3->i[3];
+}
+
+static void
+micro_ult(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1,
+   const union tgsi_exec_channel *src2,
+   const union tgsi_exec_channel *src3 )
+{
+   dst->u[0] = src0->u[0] < src1->u[0] ? src2->u[0] : src3->u[0];
+   dst->u[1] = src0->u[1] < src1->u[1] ? src2->u[1] : src3->u[1];
+   dst->u[2] = src0->u[2] < src1->u[2] ? src2->u[2] : src3->u[2];
+   dst->u[3] = src0->u[3] < src1->u[3] ? src2->u[3] : src3->u[3];
+}
+
+static void
+micro_max(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->f[0] = src0->f[0] > src1->f[0] ? src0->f[0] : src1->f[0];
+   dst->f[1] = src0->f[1] > src1->f[1] ? src0->f[1] : src1->f[1];
+   dst->f[2] = src0->f[2] > src1->f[2] ? src0->f[2] : src1->f[2];
+   dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3];
+}
+
+static void
+micro_imax(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->i[0] = src0->i[0] > src1->i[0] ? src0->i[0] : src1->i[0];
+   dst->i[1] = src0->i[1] > src1->i[1] ? src0->i[1] : src1->i[1];
+   dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2];
+   dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3];
+}
+
+static void
+micro_umax(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->u[0] = src0->u[0] > src1->u[0] ? src0->u[0] : src1->u[0];
+   dst->u[1] = src0->u[1] > src1->u[1] ? src0->u[1] : src1->u[1];
+   dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2];
+   dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3];
+}
+
+static void
+micro_min(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->f[0] = src0->f[0] < src1->f[0] ? src0->f[0] : src1->f[0];
+   dst->f[1] = src0->f[1] < src1->f[1] ? src0->f[1] : src1->f[1];
+   dst->f[2] = src0->f[2] < src1->f[2] ? src0->f[2] : src1->f[2];
+   dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3];
+}
+
+static void
+micro_imin(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->i[0] = src0->i[0] < src1->i[0] ? src0->i[0] : src1->i[0];
+   dst->i[1] = src0->i[1] < src1->i[1] ? src0->i[1] : src1->i[1];
+   dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2];
+   dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3];
+}
+
+static void
+micro_umin(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->u[0] = src0->u[0] < src1->u[0] ? src0->u[0] : src1->u[0];
+   dst->u[1] = src0->u[1] < src1->u[1] ? src0->u[1] : src1->u[1];
+   dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2];
+   dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3];
+}
+
+static void
+micro_umod(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->u[0] = src0->u[0] % src1->u[0];
+   dst->u[1] = src0->u[1] % src1->u[1];
+   dst->u[2] = src0->u[2] % src1->u[2];
+   dst->u[3] = src0->u[3] % src1->u[3];
+}
+
+static void
+micro_mul(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->f[0] = src0->f[0] * src1->f[0];
+   dst->f[1] = src0->f[1] * src1->f[1];
+   dst->f[2] = src0->f[2] * src1->f[2];
+   dst->f[3] = src0->f[3] * src1->f[3];
+}
+
+static void
+micro_imul(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->i[0] = src0->i[0] * src1->i[0];
+   dst->i[1] = src0->i[1] * src1->i[1];
+   dst->i[2] = src0->i[2] * src1->i[2];
+   dst->i[3] = src0->i[3] * src1->i[3];
+}
+
+static void
+micro_imul64(
+   union tgsi_exec_channel *dst0,
+   union tgsi_exec_channel *dst1,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst1->i[0] = src0->i[0] * src1->i[0];
+   dst1->i[1] = src0->i[1] * src1->i[1];
+   dst1->i[2] = src0->i[2] * src1->i[2];
+   dst1->i[3] = src0->i[3] * src1->i[3];
+   dst0->i[0] = 0;
+   dst0->i[1] = 0;
+   dst0->i[2] = 0;
+   dst0->i[3] = 0;
+}
+
+static void
+micro_umul64(
+   union tgsi_exec_channel *dst0,
+   union tgsi_exec_channel *dst1,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst1->u[0] = src0->u[0] * src1->u[0];
+   dst1->u[1] = src0->u[1] * src1->u[1];
+   dst1->u[2] = src0->u[2] * src1->u[2];
+   dst1->u[3] = src0->u[3] * src1->u[3];
+   dst0->u[0] = 0;
+   dst0->u[1] = 0;
+   dst0->u[2] = 0;
+   dst0->u[3] = 0;
+}
+
+static void
+micro_movc(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1,
+   const union tgsi_exec_channel *src2 )
+{
+   dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0];
+   dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1];
+   dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2];
+   dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3];
+}
+
+static void
+micro_neg(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = -src->f[0];
+   dst->f[1] = -src->f[1];
+   dst->f[2] = -src->f[2];
+   dst->f[3] = -src->f[3];
+}
+
+static void
+micro_ineg(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->i[0] = -src->i[0];
+   dst->i[1] = -src->i[1];
+   dst->i[2] = -src->i[2];
+   dst->i[3] = -src->i[3];
+}
+
+static void
+micro_not(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->u[0] = ~src->u[0];
+   dst->u[1] = ~src->u[1];
+   dst->u[2] = ~src->u[2];
+   dst->u[3] = ~src->u[3];
+}
+
+static void
+micro_or(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->u[0] = src0->u[0] | src1->u[0];
+   dst->u[1] = src0->u[1] | src1->u[1];
+   dst->u[2] = src0->u[2] | src1->u[2];
+   dst->u[3] = src0->u[3] | src1->u[3];
+}
+
+static void
+micro_pow(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->f[0] = (GLfloat) pow( (GLdouble) src0->f[0], (GLdouble) src1->f[0] );
+   dst->f[1] = (GLfloat) pow( (GLdouble) src0->f[1], (GLdouble) src1->f[1] );
+   dst->f[2] = (GLfloat) pow( (GLdouble) src0->f[2], (GLdouble) src1->f[2] );
+   dst->f[3] = (GLfloat) pow( (GLdouble) src0->f[3], (GLdouble) src1->f[3] );
+}
+
+static void
+micro_rnd(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) floor( (GLdouble) (src->f[0] + 0.5f) );
+   dst->f[1] = (GLfloat) floor( (GLdouble) (src->f[1] + 0.5f) );
+   dst->f[2] = (GLfloat) floor( (GLdouble) (src->f[2] + 0.5f) );
+   dst->f[3] = (GLfloat) floor( (GLdouble) (src->f[3] + 0.5f) );
+}
+
+static void
+micro_shl(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->i[0] = src0->i[0] << src1->i[0];
+   dst->i[1] = src0->i[1] << src1->i[1];
+   dst->i[2] = src0->i[2] << src1->i[2];
+   dst->i[3] = src0->i[3] << src1->i[3];
+}
+
+static void
+micro_ishr(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->i[0] = src0->i[0] >> src1->i[0];
+   dst->i[1] = src0->i[1] >> src1->i[1];
+   dst->i[2] = src0->i[2] >> src1->i[2];
+   dst->i[3] = src0->i[3] >> src1->i[3];
+}
+
+static void
+micro_ushr(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->u[0] = src0->u[0] >> src1->u[0];
+   dst->u[1] = src0->u[1] >> src1->u[1];
+   dst->u[2] = src0->u[2] >> src1->u[2];
+   dst->u[3] = src0->u[3] >> src1->u[3];
+}
+
+static void
+micro_sin(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) sin( (GLdouble) src->f[0] );
+   dst->f[1] = (GLfloat) sin( (GLdouble) src->f[1] );
+   dst->f[2] = (GLfloat) sin( (GLdouble) src->f[2] );
+   dst->f[3] = (GLfloat) sin( (GLdouble) src->f[3] );
+}
+
+static void
+micro_sqrt( union tgsi_exec_channel *dst,
+            const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) sqrt( (GLdouble) src->f[0] );
+   dst->f[1] = (GLfloat) sqrt( (GLdouble) src->f[1] );
+   dst->f[2] = (GLfloat) sqrt( (GLdouble) src->f[2] );
+   dst->f[3] = (GLfloat) sqrt( (GLdouble) src->f[3] );
+}
+
+static void
+micro_sub(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->f[0] = src0->f[0] - src1->f[0];
+   dst->f[1] = src0->f[1] - src1->f[1];
+   dst->f[2] = src0->f[2] - src1->f[2];
+   dst->f[3] = src0->f[3] - src1->f[3];
+}
+
+static void
+micro_u2f(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src )
+{
+   dst->f[0] = (GLfloat) src->u[0];
+   dst->f[1] = (GLfloat) src->u[1];
+   dst->f[2] = (GLfloat) src->u[2];
+   dst->f[3] = (GLfloat) src->u[3];
+}
+
+static void
+micro_xor(
+   union tgsi_exec_channel *dst,
+   const union tgsi_exec_channel *src0,
+   const union tgsi_exec_channel *src1 )
+{
+   dst->u[0] = src0->u[0] ^ src1->u[0];
+   dst->u[1] = src0->u[1] ^ src1->u[1];
+   dst->u[2] = src0->u[2] ^ src1->u[2];
+   dst->u[3] = src0->u[3] ^ src1->u[3];
+}
+
+static void
+fetch_src_file_channel(
+   const struct tgsi_exec_machine *mach,
+   const GLuint file,
+   const GLuint swizzle,
+   const union tgsi_exec_channel *index,
+   union tgsi_exec_channel *chan )
+{
+   switch( swizzle ) {
+   case TGSI_EXTSWIZZLE_X:
+   case TGSI_EXTSWIZZLE_Y:
+   case TGSI_EXTSWIZZLE_Z:
+   case TGSI_EXTSWIZZLE_W:
+      switch( file ) {
+      case TGSI_FILE_CONSTANT:
+         chan->f[0] = mach->Consts[index->i[0]][swizzle];
+         chan->f[1] = mach->Consts[index->i[1]][swizzle];
+         chan->f[2] = mach->Consts[index->i[2]][swizzle];
+         chan->f[3] = mach->Consts[index->i[3]][swizzle];
+         break;
+
+      case TGSI_FILE_INPUT:
+         chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0];
+         chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1];
+         chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2];
+         chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3];
+         break;
+
+      case TGSI_FILE_TEMPORARY:
+         chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0];
+         chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1];
+         chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2];
+         chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3];
+         break;
+
+      case TGSI_FILE_IMMEDIATE:
+         assert( index->i[0] < (GLint) mach->ImmLimit );
+         chan->f[0] = mach->Imms[index->i[0]][swizzle];
+         assert( index->i[1] < (GLint) mach->ImmLimit );
+         chan->f[1] = mach->Imms[index->i[1]][swizzle];
+         assert( index->i[2] < (GLint) mach->ImmLimit );
+         chan->f[2] = mach->Imms[index->i[2]][swizzle];
+         assert( index->i[3] < (GLint) mach->ImmLimit );
+         chan->f[3] = mach->Imms[index->i[3]][swizzle];
+         break;
+
+      case TGSI_FILE_ADDRESS:
+         chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0];
+         chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1];
+         chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2];
+         chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3];
+         break;
+
+      default:
+         assert( 0 );
+      }
+      break;
+
+   case TGSI_EXTSWIZZLE_ZERO:
+      *chan = mach->Temps[TEMP_0_I].xyzw[TEMP_0_C];
+      break;
+
+   case TGSI_EXTSWIZZLE_ONE:
+      *chan = mach->Temps[TEMP_1_I].xyzw[TEMP_1_C];
+      break;
+
+   default:
+      assert( 0 );
+   }
+}
+
+static void
+fetch_source(
+   const struct tgsi_exec_machine *mach,
+   union tgsi_exec_channel *chan,
+   const struct tgsi_full_src_register *reg,
+   const GLuint chan_index )
+{
+   union tgsi_exec_channel index;
+   GLuint swizzle;
+
+   index.i[0] =
+   index.i[1] =
+   index.i[2] =
+   index.i[3] = reg->SrcRegister.Index;
+
+   if (reg->SrcRegister.Indirect) {
+      union tgsi_exec_channel index2;
+      union tgsi_exec_channel indir_index;
+
+      index2.i[0] =
+      index2.i[1] =
+      index2.i[2] =
+      index2.i[3] = reg->SrcRegisterInd.Index;
+
+      swizzle = tgsi_util_get_src_register_swizzle( &reg->SrcRegisterInd, CHAN_X );
+      fetch_src_file_channel(
+         mach,
+         reg->SrcRegisterInd.File,
+         swizzle,
+         &index2,
+         &indir_index );
+
+      index.i[0] += indir_index.i[0];
+      index.i[1] += indir_index.i[1];
+      index.i[2] += indir_index.i[2];
+      index.i[3] += indir_index.i[3];
+   }
+
+   if( reg->SrcRegister.Dimension ) {
+      switch( reg->SrcRegister.File ) {
+      case TGSI_FILE_INPUT:
+         index.i[0] *= 17;
+         index.i[1] *= 17;
+         index.i[2] *= 17;
+         index.i[3] *= 17;
+         break;
+      case TGSI_FILE_CONSTANT:
+         index.i[0] *= 4096;
+         index.i[1] *= 4096;
+         index.i[2] *= 4096;
+         index.i[3] *= 4096;
+         break;
+      default:
+         assert( 0 );
+      }
+
+      index.i[0] += reg->SrcRegisterDim.Index;
+      index.i[1] += reg->SrcRegisterDim.Index;
+      index.i[2] += reg->SrcRegisterDim.Index;
+      index.i[3] += reg->SrcRegisterDim.Index;
+
+      if (reg->SrcRegisterDim.Indirect) {
+         union tgsi_exec_channel index2;
+         union tgsi_exec_channel indir_index;
+
+         index2.i[0] =
+         index2.i[1] =
+         index2.i[2] =
+         index2.i[3] = reg->SrcRegisterDimInd.Index;
+
+         swizzle = tgsi_util_get_src_register_swizzle( &reg->SrcRegisterDimInd, CHAN_X );
+         fetch_src_file_channel(
+            mach,
+            reg->SrcRegisterDimInd.File,
+            swizzle,
+            &index2,
+            &indir_index );
+
+         index.i[0] += indir_index.i[0];
+         index.i[1] += indir_index.i[1];
+         index.i[2] += indir_index.i[2];
+         index.i[3] += indir_index.i[3];
+      }
+   }
+
+   swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index );
+   fetch_src_file_channel(
+      mach,
+      reg->SrcRegister.File,
+      swizzle,
+      &index,
+      chan );
+
+   switch (tgsi_util_get_full_src_register_sign_mode( reg, chan_index )) {
+   case TGSI_UTIL_SIGN_CLEAR:
+      micro_abs( chan, chan );
+      break;
+
+   case TGSI_UTIL_SIGN_SET:
+      micro_abs( chan, chan );
+      micro_neg( chan, chan );
+      break;
+
+   case TGSI_UTIL_SIGN_TOGGLE:
+      micro_neg( chan, chan );
+      break;
+
+   case TGSI_UTIL_SIGN_KEEP:
+      break;
+   }
+}
+
+static void
+store_dest(
+   struct tgsi_exec_machine *mach,
+   const union tgsi_exec_channel *chan,
+   const struct tgsi_full_dst_register *reg,
+   const struct tgsi_full_instruction *inst,
+   GLuint chan_index )
+{
+   union tgsi_exec_channel *dst;
+
+   switch( reg->DstRegister.File ) {
+   case TGSI_FILE_NULL:
+      return;
+
+   case TGSI_FILE_OUTPUT:
+      dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] + reg->DstRegister.Index].xyzw[chan_index];
+      break;
+
+   case TGSI_FILE_TEMPORARY:
+      dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index];
+      break;
+
+   case TGSI_FILE_ADDRESS:
+      dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index];
+      break;
+
+   default:
+      assert( 0 );
+   }
+
+   switch (inst->Instruction.Saturate)
+   {
+   case TGSI_SAT_NONE:
+      *dst = *chan;
+      break;
+
+   case TGSI_SAT_ZERO_ONE:
+      micro_lt( dst, chan, &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], chan );
+      micro_lt( dst, chan, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], chan, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] );
+      break;
+
+   case TGSI_SAT_MINUS_PLUS_ONE:
+      assert( 0 );
+      break;
+
+   default:
+      assert( 0 );
+   }
+}
+
+#define FETCH(VAL,INDEX,CHAN)\
+    fetch_source (mach, VAL, &inst->FullSrcRegisters[INDEX], CHAN)
+
+#define STORE(VAL,INDEX,CHAN)\
+    store_dest (mach, VAL, &inst->FullDstRegisters[INDEX], inst, CHAN)
+
+static void
+exec_kil (struct tgsi_exec_machine *mach,
+          const struct tgsi_full_instruction *inst)
+{
+    GLuint uniquemask;
+    GLuint chan_index;
+    GLuint kilmask = 0;
+    union tgsi_exec_channel r[1];
+
+    /* This mask stores component bits that were already tested. Note that
+     * we test if the value is less than zero, so 1.0 and 0.0 need not to be
+     * tested. */
+    uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE);
+
+    for (chan_index = 0; chan_index < 4; chan_index++)
+    {
+        GLuint swizzle;
+        GLuint i;
+
+        /* unswizzle channel */
+        swizzle = tgsi_util_get_full_src_register_extswizzle (
+                        &inst->FullSrcRegisters[0],
+                        chan_index);
+
+        /* check if the component has not been already tested */
+        if (uniquemask & (1 << swizzle))
+            continue;
+        uniquemask |= 1 << swizzle;
+
+        FETCH(&r[0], 0, chan_index);
+        for (i = 0; i < 4; i++)
+            if (r[0].f[i] < 0.0f)
+                kilmask |= 1 << (i * 4);
+    }
+
+    mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask;
+}
+
+#if MESA
+/*
+ * Fetch a texel using S texture coordinate.
+ */
+static void
+fetch_texel_1d( GLcontext *ctx,
+                struct tgsi_sampler_state *sampler,
+                const union tgsi_exec_channel *s,
+                GLuint unit,
+                union tgsi_exec_channel *r,
+                union tgsi_exec_channel *g,
+                union tgsi_exec_channel *b,
+                union tgsi_exec_channel *a )
+{
+    SWcontext *swrast = SWRAST_CONTEXT(ctx);
+    GLuint fragment_index;
+    GLfloat stpq[4][4];
+    GLfloat lambdas[4];
+    GLchan rgba[4][4];
+
+    for (fragment_index = 0; fragment_index < 4; fragment_index++)
+    {
+        stpq[fragment_index][0] = s->f[fragment_index];
+    }
+
+    if (sampler->NeedLambda)
+    {
+        GLfloat dsdx = s->f[TILE_BOTTOM_RIGHT] - s->f[TILE_BOTTOM_LEFT];
+        GLfloat dsdy = s->f[TILE_TOP_LEFT]     - s->f[TILE_BOTTOM_LEFT];
+
+        GLfloat rho, lambda;
+
+        dsdx = FABSF(dsdx);
+        dsdy = FABSF(dsdy);
+
+        rho = MAX2(dsdx, dsdy) * sampler->ImageWidth;
+
+        lambda = LOG2(rho);
+
+        if (sampler->NeedLodBias)
+            lambda += sampler->LodBias;
+
+        if (sampler->NeedLambdaClamp)
+            lambda = CLAMP(lambda, sampler->MinLod, sampler->MaxLod);
+
+        /* XXX: Use the same lambda value throughout the tile.  Could
+         * end up with four unique values by recalculating partial
+         * derivs in the other row and column, and calculating lambda
+         * using the dx and dy values appropriate for each fragment in
+         * the tile.
+         */
+        lambdas[0] =
+        lambdas[1] =
+        lambdas[2] = 
+        lambdas[3] = lambda;
+    }
+
+    if (!swrast->TextureSample[unit]) {
+       _swrast_update_texture_samplers(ctx);
+    }
+
+    /* XXX use a float-valued TextureSample routine here!!! */
+    swrast->TextureSample[unit] (ctx,
+                                 ctx->Texture.Unit[unit]._Current,
+                                 4,
+                                 (const GLfloat (*)[4])stpq,
+                                 lambdas,
+                                 rgba);
+
+    for (fragment_index = 0; fragment_index < 4; fragment_index++)
+    {
+        r->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][0]);
+        g->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][1]);
+        b->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][2]);
+        a->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][3]);
+    }
+}
+
+/*
+ * Fetch a texel using ST texture coordinates.
+ */
+static void
+fetch_texel_2d( GLcontext *ctx,
+                struct tgsi_sampler_state *sampler,
+                const union tgsi_exec_channel *s,
+                const union tgsi_exec_channel *t,
+                GLuint unit,
+                union tgsi_exec_channel *r,
+                union tgsi_exec_channel *g,
+                union tgsi_exec_channel *b,
+                union tgsi_exec_channel *a )
+{
+   SWcontext *swrast = SWRAST_CONTEXT( ctx );
+   GLuint fragment_index;
+   GLfloat stpq[4][4];
+   GLfloat lambdas[4];
+   GLchan rgba[4][4];
+
+   for (fragment_index = 0; fragment_index < 4; fragment_index++) {
+      stpq[fragment_index][0] = s->f[fragment_index];
+      stpq[fragment_index][1] = t->f[fragment_index];
+   }
+
+   if (sampler->NeedLambda) {
+      GLfloat dsdx = s->f[TILE_BOTTOM_RIGHT] - s->f[TILE_BOTTOM_LEFT];
+      GLfloat dsdy = s->f[TILE_TOP_LEFT]     - s->f[TILE_BOTTOM_LEFT];
+
+      GLfloat dtdx = t->f[TILE_BOTTOM_RIGHT] - t->f[TILE_BOTTOM_LEFT];
+      GLfloat dtdy = t->f[TILE_TOP_LEFT]     - t->f[TILE_BOTTOM_LEFT];
+
+      GLfloat maxU, maxV, rho, lambda;
+
+      dsdx = FABSF( dsdx );
+      dsdy = FABSF( dsdy );
+      dtdx = FABSF( dtdx );
+      dtdy = FABSF( dtdy );
+
+      maxU = MAX2( dsdx, dsdy ) * sampler->ImageWidth;
+      maxV = MAX2( dtdx, dtdy ) * sampler->ImageHeight;
+
+      rho = MAX2( maxU, maxV );
+
+      lambda = LOG2( rho );
+
+      if (sampler->NeedLodBias)
+        lambda += sampler->LodBias;
+
+      if (sampler->NeedLambdaClamp)
+         lambda = CLAMP(
+                    lambda,
+                    sampler->MinLod,
+                    sampler->MaxLod );
+
+      /* XXX: Use the same lambda value throughout the tile.  Could
+        * end up with four unique values by recalculating partial
+        * derivs in the other row and column, and calculating lambda
+        * using the dx and dy values appropriate for each fragment in
+        * the tile.
+        */
+      lambdas[0] =
+      lambdas[1] =
+      lambdas[2] = 
+      lambdas[3] = lambda;
+   }
+
+   if (!swrast->TextureSample[unit]) {
+      _swrast_update_texture_samplers(ctx);
+   }
+
+   /* XXX use a float-valued TextureSample routine here!!! */
+   swrast->TextureSample[unit](
+      ctx,
+      ctx->Texture.Unit[unit]._Current,
+      4,
+      (const GLfloat (*)[4]) stpq,
+      lambdas,
+      rgba );
+
+   for (fragment_index = 0; fragment_index < 4; fragment_index++) {
+      r->f[fragment_index] = CHAN_TO_FLOAT( rgba[fragment_index][0] );
+      g->f[fragment_index] = CHAN_TO_FLOAT( rgba[fragment_index][1] );
+      b->f[fragment_index] = CHAN_TO_FLOAT( rgba[fragment_index][2] );
+      a->f[fragment_index] = CHAN_TO_FLOAT( rgba[fragment_index][3] );
+   }
+}
+
+/*
+ * Fetch a texel using STR texture coordinates.
+ */
+static void
+fetch_texel_3d( GLcontext *ctx,
+                struct tgsi_sampler_state *sampler,
+                const union tgsi_exec_channel *s,
+                const union tgsi_exec_channel *t,
+                const union tgsi_exec_channel *p,
+                GLuint unit,
+                union tgsi_exec_channel *r,
+                union tgsi_exec_channel *g,
+                union tgsi_exec_channel *b,
+                union tgsi_exec_channel *a )
+{
+    SWcontext *swrast = SWRAST_CONTEXT(ctx);
+    GLuint fragment_index;
+    GLfloat stpq[4][4];
+    GLfloat lambdas[4];
+    GLchan rgba[4][4];
+
+    for (fragment_index = 0; fragment_index < 4; fragment_index++)
+    {
+        stpq[fragment_index][0] = s->f[fragment_index];
+        stpq[fragment_index][1] = t->f[fragment_index];
+        stpq[fragment_index][2] = p->f[fragment_index];
+    }
+
+    if (sampler->NeedLambda)
+    {
+        GLfloat dsdx = s->f[TILE_BOTTOM_RIGHT] - s->f[TILE_BOTTOM_LEFT];
+        GLfloat dsdy = s->f[TILE_TOP_LEFT]     - s->f[TILE_BOTTOM_LEFT];
+
+        GLfloat dtdx = t->f[TILE_BOTTOM_RIGHT] - t->f[TILE_BOTTOM_LEFT];
+        GLfloat dtdy = t->f[TILE_TOP_LEFT]     - t->f[TILE_BOTTOM_LEFT];
+
+        GLfloat dpdx = p->f[TILE_BOTTOM_RIGHT] - p->f[TILE_BOTTOM_LEFT];
+        GLfloat dpdy = p->f[TILE_TOP_LEFT]     - p->f[TILE_BOTTOM_LEFT];
+
+        GLfloat maxU, maxV, maxW, rho, lambda;
+
+        dsdx = FABSF(dsdx);
+        dsdy = FABSF(dsdy);
+        dtdx = FABSF(dtdx);
+        dtdy = FABSF(dtdy);
+        dpdx = FABSF(dpdx);
+        dpdy = FABSF(dpdy);
+
+        maxU = MAX2(dsdx, dsdy) * sampler->ImageWidth;
+        maxV = MAX2(dtdx, dtdy) * sampler->ImageHeight;
+        maxW = MAX2(dpdx, dpdy) * sampler->ImageDepth;
+
+        rho = MAX2(maxU, MAX2(maxV, maxW));
+
+        lambda = LOG2(rho);
+
+        if (sampler->NeedLodBias)
+            lambda += sampler->LodBias;
+
+        if (sampler->NeedLambdaClamp)
+            lambda = CLAMP(lambda, sampler->MinLod, sampler->MaxLod);
+
+        /* XXX: Use the same lambda value throughout the tile.  Could
+         * end up with four unique values by recalculating partial
+         * derivs in the other row and column, and calculating lambda
+         * using the dx and dy values appropriate for each fragment in
+         * the tile.
+         */
+        lambdas[0] =
+        lambdas[1] =
+        lambdas[2] = 
+        lambdas[3] = lambda;
+    }
+
+    if (!swrast->TextureSample[unit]) {
+       _swrast_update_texture_samplers(ctx);
+    }
+
+    /* XXX use a float-valued TextureSample routine here!!! */
+    swrast->TextureSample[unit] (ctx,
+                                 ctx->Texture.Unit[unit]._Current,
+                                 4,
+                                 (const GLfloat (*)[4])stpq,
+                                 lambdas,
+                                 rgba);
+
+    for (fragment_index = 0; fragment_index < 4; fragment_index++)
+    {
+        r->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][0]);
+        g->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][1]);
+        b->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][2]);
+        a->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][3]);
+    }
+}
+#endif
+
+static GLuint
+map_label(
+   GLuint label,
+   struct tgsi_exec_labels *labels )
+{
+   GLuint i;
+
+   for( i = 0; i < labels->count; i++ ) {
+      if( labels->labels[i][0] == label ) {
+         return labels->labels[i][1];
+      }
+   }
+   assert( 0 );
+   return 0;
+}
+
+static void
+exec_instruction(
+   struct tgsi_exec_machine *mach,
+   const struct tgsi_full_instruction *inst,
+   struct tgsi_exec_labels *labels,
+   GLuint *programCounter )
+{
+#if MESA
+   GET_CURRENT_CONTEXT(ctx);
+#endif
+   GLuint chan_index;
+   union tgsi_exec_channel r[8];
+
+   switch (inst->Instruction.Opcode) {
+   case TGSI_OPCODE_ARL:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+        FETCH( &r[0], 0, chan_index );
+        micro_f2it( &r[0], &r[0] );
+        STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_MOV:
+   /* TGSI_OPCODE_SWZ */
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_LIT:
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
+        STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X );
+      }
+
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_Y ) || IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
+        FETCH( &r[0], 0, CHAN_X );
+        if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) {
+           micro_max( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] );
+           STORE( &r[0], 0, CHAN_Y );
+        }
+
+        if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
+           FETCH( &r[1], 0, CHAN_Y );
+           micro_max( &r[1], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] );
+
+           FETCH( &r[2], 0, CHAN_W );
+           micro_min( &r[2], &r[2], &mach->Temps[TEMP_128_I].xyzw[TEMP_128_C] );
+           micro_max( &r[2], &r[2], &mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C] );
+           micro_pow( &r[1], &r[1], &r[2] );
+           micro_lt( &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] );
+           STORE( &r[0], 0, CHAN_Z );
+        }
+      }
+
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
+        STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W );
+      }
+      break;
+
+   case TGSI_OPCODE_RCP:
+   /* TGSI_OPCODE_RECIP */
+      FETCH( &r[0], 0, CHAN_X );
+      micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] );
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+        STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_RSQ:
+   /* TGSI_OPCODE_RECIPSQRT */
+      FETCH( &r[0], 0, CHAN_X );
+      micro_sqrt( &r[0], &r[0] );
+      micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] );
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+        STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_EXP:
+      assert (0);
+      break;
+
+    case TGSI_OPCODE_LOG:
+        assert (0);
+        break;
+
+    case TGSI_OPCODE_MUL:
+        FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
+        {
+            FETCH(&r[0], 0, chan_index);
+            FETCH(&r[1], 1, chan_index);
+
+            micro_mul( &r[0], &r[0], &r[1] );
+
+            STORE(&r[0], 0, chan_index);
+        }
+        break;
+
+   case TGSI_OPCODE_ADD:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         FETCH( &r[1], 1, chan_index );
+         micro_add( &r[0], &r[0], &r[1] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_DP3:
+   /* TGSI_OPCODE_DOT3 */
+      FETCH( &r[0], 0, CHAN_X );
+      FETCH( &r[1], 1, CHAN_X );
+      micro_mul( &r[0], &r[0], &r[1] );
+
+      FETCH( &r[1], 0, CHAN_Y );
+      FETCH( &r[2], 1, CHAN_Y );
+      micro_mul( &r[1], &r[1], &r[2] );
+      micro_add( &r[0], &r[0], &r[1] );
+
+      FETCH( &r[1], 0, CHAN_Z );
+      FETCH( &r[2], 1, CHAN_Z );
+      micro_mul( &r[1], &r[1], &r[2] );
+      micro_add( &r[0], &r[0], &r[1] );
+
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+    case TGSI_OPCODE_DP4:
+    /* TGSI_OPCODE_DOT4 */
+       FETCH(&r[0], 0, CHAN_X);
+       FETCH(&r[1], 1, CHAN_X);
+
+       micro_mul( &r[0], &r[0], &r[1] );
+
+       FETCH(&r[1], 0, CHAN_Y);
+       FETCH(&r[2], 1, CHAN_Y);
+
+       micro_mul( &r[1], &r[1], &r[2] );
+       micro_add( &r[0], &r[0], &r[1] );
+
+       FETCH(&r[1], 0, CHAN_Z);
+       FETCH(&r[2], 1, CHAN_Z);
+
+       micro_mul( &r[1], &r[1], &r[2] );
+       micro_add( &r[0], &r[0], &r[1] );
+
+       FETCH(&r[1], 0, CHAN_W);
+       FETCH(&r[2], 1, CHAN_W);
+
+       micro_mul( &r[1], &r[1], &r[2] );
+       micro_add( &r[0], &r[0], &r[1] );
+
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+        STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_DST:
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
+        STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X );
+      }
+
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) {
+        FETCH( &r[0], 0, CHAN_Y );
+        FETCH( &r[1], 1, CHAN_Y);
+        micro_mul( &r[0], &r[0], &r[1] );
+        STORE( &r[0], 0, CHAN_Y );
+      }
+
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
+        FETCH( &r[0], 0, CHAN_Z );
+        STORE( &r[0], 0, CHAN_Z );
+      }
+
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
+        FETCH( &r[0], 1, CHAN_W );
+        STORE( &r[0], 0, CHAN_W );
+      }
+      break;
+
+   case TGSI_OPCODE_MIN:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH(&r[0], 0, chan_index);
+         FETCH(&r[1], 1, chan_index);
+
+         micro_lt( &r[0], &r[0], &r[1], &r[0], &r[1] );
+
+         STORE(&r[0], 0, chan_index);
+      }
+      break;
+
+   case TGSI_OPCODE_MAX:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH(&r[0], 0, chan_index);
+         FETCH(&r[1], 1, chan_index);
+
+         micro_lt( &r[0], &r[0], &r[1], &r[1], &r[0] );
+
+         STORE(&r[0], 0, chan_index);
+      }
+      break;
+
+   case TGSI_OPCODE_SLT:
+   /* TGSI_OPCODE_SETLT */
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         FETCH( &r[1], 1, chan_index );
+         micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_SGE:
+   /* TGSI_OPCODE_SETGE */
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH(&r[0], 0, chan_index);
+         FETCH(&r[1], 1, chan_index);
+
+         micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] );
+
+         STORE(&r[0], 0, chan_index);
+      }
+      break;
+
+   case TGSI_OPCODE_MAD:
+   /* TGSI_OPCODE_MADD */
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         FETCH( &r[1], 1, chan_index );
+         micro_mul( &r[0], &r[0], &r[1] );
+         FETCH( &r[1], 2, chan_index );
+         micro_add( &r[0], &r[0], &r[1] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+    case TGSI_OPCODE_SUB:
+       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+          FETCH(&r[0], 0, chan_index);
+          FETCH(&r[1], 1, chan_index);
+
+          micro_sub( &r[0], &r[0], &r[1] );
+
+          STORE(&r[0], 0, chan_index);
+       }
+       break;
+
+   case TGSI_OPCODE_LERP:
+   /* TGSI_OPCODE_LRP */
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH(&r[0], 0, chan_index);
+         FETCH(&r[1], 1, chan_index);
+         FETCH(&r[2], 2, chan_index);
+
+         micro_sub( &r[1], &r[1], &r[2] );
+         micro_mul( &r[0], &r[0], &r[1] );
+         micro_add( &r[0], &r[0], &r[2] );
+
+         STORE(&r[0], 0, chan_index);
+      }
+      break;
+
+   case TGSI_OPCODE_CND:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_CND0:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_DOT2ADD:
+      /* TGSI_OPCODE_DP2A */
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_INDEX:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_NEGATE:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_FRAC:
+   /* TGSI_OPCODE_FRC */
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         micro_frc( &r[0], &r[0] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_CLAMP:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_FLOOR:
+   /* TGSI_OPCODE_FLR */
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         micro_flr( &r[0], &r[0] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_ROUND:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         micro_rnd( &r[0], &r[0] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_EXPBASE2:
+    /* TGSI_OPCODE_EX2 */
+      FETCH(&r[0], 0, CHAN_X);
+
+      micro_pow( &r[0], &mach->Temps[TEMP_2_I].xyzw[TEMP_2_C], &r[0] );
+
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+        STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_LOGBASE2:
+   /* TGSI_OPCODE_LG2 */
+      FETCH( &r[0], 0, CHAN_X );
+      micro_lg2( &r[0], &r[0] );
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_POWER:
+      /* TGSI_OPCODE_POW */
+      FETCH(&r[0], 0, CHAN_X);
+      FETCH(&r[1], 1, CHAN_X);
+
+      micro_pow( &r[0], &r[0], &r[1] );
+
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+        STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_CROSSPRODUCT:
+      /* TGSI_OPCODE_XPD */
+      FETCH(&r[0], 0, CHAN_Y);
+      FETCH(&r[1], 1, CHAN_Z);
+
+      micro_mul( &r[2], &r[0], &r[1] );
+
+      FETCH(&r[3], 0, CHAN_Z);
+      FETCH(&r[4], 1, CHAN_Y);
+
+      micro_mul( &r[5], &r[3], &r[4] );
+      micro_sub( &r[2], &r[2], &r[5] );
+
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
+        STORE( &r[2], 0, CHAN_X );
+      }
+
+      FETCH(&r[2], 1, CHAN_X);
+
+      micro_mul( &r[3], &r[3], &r[2] );
+
+      FETCH(&r[5], 0, CHAN_X);
+
+      micro_mul( &r[1], &r[1], &r[5] );
+      micro_sub( &r[3], &r[3], &r[1] );
+
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) {
+        STORE( &r[3], 0, CHAN_Y );
+      }
+
+      micro_mul( &r[5], &r[5], &r[4] );
+      micro_mul( &r[0], &r[0], &r[2] );
+      micro_sub( &r[5], &r[5], &r[0] );
+
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
+        STORE( &r[5], 0, CHAN_Z );
+      }
+
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
+        STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W );
+      }
+      break;
+
+    case TGSI_OPCODE_MULTIPLYMATRIX:
+       assert (0);
+       break;
+
+    case TGSI_OPCODE_ABS:
+       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+          FETCH(&r[0], 0, chan_index);
+
+          micro_abs( &r[0], &r[0] );
+
+          STORE(&r[0], 0, chan_index);
+       }
+       break;
+
+   case TGSI_OPCODE_RCC:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_DPH:
+      FETCH(&r[0], 0, CHAN_X);
+      FETCH(&r[1], 1, CHAN_X);
+
+      micro_mul( &r[0], &r[0], &r[1] );
+
+      FETCH(&r[1], 0, CHAN_Y);
+      FETCH(&r[2], 1, CHAN_Y);
+
+      micro_mul( &r[1], &r[1], &r[2] );
+      micro_add( &r[0], &r[0], &r[1] );
+
+      FETCH(&r[1], 0, CHAN_Z);
+      FETCH(&r[2], 1, CHAN_Z);
+
+      micro_mul( &r[1], &r[1], &r[2] );
+      micro_add( &r[0], &r[0], &r[1] );
+
+      FETCH(&r[1], 1, CHAN_W);
+
+      micro_add( &r[0], &r[0], &r[1] );
+
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+        STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_COS:
+      FETCH(&r[0], 0, CHAN_X);
+
+      micro_cos( &r[0], &r[0] );
+
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+        STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_DDX:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         micro_ddx( &r[0], &r[0] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_DDY:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         micro_ddy( &r[0], &r[0] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_KIL:
+       exec_kil (mach, inst);
+       break;
+
+   case TGSI_OPCODE_PK2H:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_PK2US:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_PK4B:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_PK4UB:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_RFL:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_SEQ:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_SFL:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_SGT:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_SIN:
+      FETCH(&r[0], 0, CHAN_X);
+
+      micro_sin( &r[0], &r[0] );
+
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+        STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_SLE:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_SNE:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_STR:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_TEX:
+      switch (inst->InstructionExtTexture.Texture) {
+      case TGSI_TEXTURE_1D:
+
+         FETCH(&r[0], 0, CHAN_X);
+
+         switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) {
+         case TGSI_EXTSWIZZLE_W:
+            FETCH(&r[1], 0, CHAN_W);
+            micro_div( &r[0], &r[0], &r[1] );
+            break;
+
+         case TGSI_EXTSWIZZLE_ONE:
+            break;
+
+         default:
+            assert (0);
+         }
+#if MESA
+         fetch_texel_1d (ctx,
+                         &mach->Samplers[inst->FullSrcRegisters[1].SrcRegister.Index],
+                         &r[0],
+                         inst->FullSrcRegisters[1].SrcRegister.Index,
+                         &r[0], &r[1], &r[2], &r[3]);
+#endif
+         break;
+
+      case TGSI_TEXTURE_2D:
+      case TGSI_TEXTURE_RECT:
+
+         FETCH(&r[0], 0, CHAN_X);
+         FETCH(&r[1], 0, CHAN_Y);
+
+         switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) {
+         case TGSI_EXTSWIZZLE_W:
+            FETCH(&r[2], 0, CHAN_W);
+            micro_div( &r[0], &r[0], &r[2] );
+            micro_div( &r[1], &r[1], &r[2] );
+            break;
+
+         case TGSI_EXTSWIZZLE_ONE:
+            break;
+
+         default:
+            assert (0);
+         }
+
+#if MESA
+         fetch_texel_2d (ctx,
+                         &mach->Samplers[inst->FullSrcRegisters[1].SrcRegister.Index],
+                         &r[0], &r[1],
+                         inst->FullSrcRegisters[1].SrcRegister.Index,
+                         &r[0], &r[1], &r[2], &r[3]);
+#endif
+         break;
+
+      case TGSI_TEXTURE_3D:
+      case TGSI_TEXTURE_CUBE:
+
+         FETCH(&r[0], 0, CHAN_X);
+         FETCH(&r[1], 0, CHAN_Y);
+         FETCH(&r[2], 0, CHAN_Z);
+
+         switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) {
+         case TGSI_EXTSWIZZLE_W:
+            FETCH(&r[3], 0, CHAN_W);
+            micro_div( &r[0], &r[0], &r[3] );
+            micro_div( &r[1], &r[1], &r[3] );
+            micro_div( &r[2], &r[2], &r[3] );
+            break;
+
+         case TGSI_EXTSWIZZLE_ONE:
+            break;
+
+         default:
+            assert (0);
+         }
+
+#if MESA
+         fetch_texel_3d (ctx,
+                         &mach->Samplers[inst->FullSrcRegisters[1].SrcRegister.Index],
+                         &r[0], &r[1], &r[2],
+                         inst->FullSrcRegisters[1].SrcRegister.Index,
+                         &r[0], &r[1], &r[2], &r[3]);
+#endif
+         break;
+
+      default:
+         assert (0);
+      }
+
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+        STORE( &r[chan_index], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_TXD:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_UP2H:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_UP2US:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_UP4B:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_UP4UB:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_X2D:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_ARA:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_ARR:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_BRA:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_CAL:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_RET:
+      /* XXX: end of shader! */
+      /*assert (0);*/
+      break;
+
+   case TGSI_OPCODE_SSG:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_CMP:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH(&r[0], 0, chan_index);
+         FETCH(&r[1], 1, chan_index);
+         FETCH(&r[2], 2, chan_index);
+
+         micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] );
+
+         STORE(&r[0], 0, chan_index);
+      }
+      break;
+
+   case TGSI_OPCODE_SCS:
+      if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) || IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) {
+         FETCH( &r[0], 0, CHAN_X );
+      }
+      if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) ) {
+         micro_cos( &r[1], &r[0] );
+         STORE( &r[1], 0, CHAN_X );
+      }
+      if( IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) {
+         micro_sin( &r[1], &r[0] );
+         STORE( &r[1], 0, CHAN_Y );
+      }
+      if( IS_CHANNEL_ENABLED( *inst, CHAN_Z ) ) {
+         STORE( &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], 0, CHAN_Z );
+      }
+      if( IS_CHANNEL_ENABLED( *inst, CHAN_W ) ) {
+         STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W );
+      }
+      break;
+
+   case TGSI_OPCODE_TXB:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_NRM:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_DIV:
+      assert( 0 );
+      break;
+
+   case TGSI_OPCODE_DP2:
+      FETCH( &r[0], 0, CHAN_X );
+      FETCH( &r[1], 1, CHAN_X );
+      micro_mul( &r[0], &r[0], &r[1] );
+
+      FETCH( &r[1], 0, CHAN_Y );
+      FETCH( &r[2], 1, CHAN_Y );
+      micro_mul( &r[1], &r[1], &r[2] );
+      micro_add( &r[0], &r[0], &r[1] );
+
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_TXL:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_BRK:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_IF:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_LOOP:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_REP:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_ELSE:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_ENDIF:
+       assert (0);
+       break;
+
+   case TGSI_OPCODE_ENDLOOP:
+       assert (0);
+       break;
+
+   case TGSI_OPCODE_ENDREP:
+       assert (0);
+       break;
+
+   case TGSI_OPCODE_PUSHA:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_POPA:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_CEIL:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         micro_ceil( &r[0], &r[0] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_I2F:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         micro_i2f( &r[0], &r[0] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_NOT:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         micro_not( &r[0], &r[0] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_TRUNC:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_SHL:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         FETCH( &r[1], 1, chan_index );
+         micro_shl( &r[0], &r[0], &r[1] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_SHR:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         FETCH( &r[1], 1, chan_index );
+         micro_ishr( &r[0], &r[0], &r[1] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_AND:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         FETCH( &r[1], 1, chan_index );
+         micro_and( &r[0], &r[0], &r[1] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_OR:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         FETCH( &r[1], 1, chan_index );
+         micro_or( &r[0], &r[0], &r[1] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_MOD:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_XOR:
+      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+         FETCH( &r[0], 0, chan_index );
+         FETCH( &r[1], 1, chan_index );
+         micro_xor( &r[0], &r[0], &r[1] );
+         STORE( &r[0], 0, chan_index );
+      }
+      break;
+
+   case TGSI_OPCODE_SAD:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_TXF:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_TXQ:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_CONT:
+      assert (0);
+      break;
+
+   case TGSI_OPCODE_EMIT:
+      mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16;
+      mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++;
+      break;
+
+   case TGSI_OPCODE_ENDPRIM:
+      mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++;
+      mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0;
+      break;
+
+   default:
+      assert( 0 );
+   }
+}
+
+
+#if !defined(XSTDCALL) 
+#if defined(WIN32)
+#define XSTDCALL __stdcall
+#else
+#define XSTDCALL
+#endif
+#endif
+
+typedef void (XSTDCALL *fp_function) (const struct tgsi_exec_vector *input,
+                                    struct tgsi_exec_vector *output,
+                                    GLfloat (*constant)[4],
+                                    struct tgsi_exec_vector *temporary);
+
+void
+tgsi_exec_machine_run2(
+   struct tgsi_exec_machine *mach,
+   struct tgsi_exec_labels *labels )
+{
+#if MESA
+   GET_CURRENT_CONTEXT(ctx);
+   GLuint i;
+#endif
+
+#if XXX_SSE
+   fp_function function;
+
+   mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0;
+    
+   function = (fp_function) x86_get_func (&mach->Function);
+
+   function (mach->Inputs,
+             mach->Outputs,
+             mach->Consts,
+             mach->Temps);
+#else
+   struct tgsi_parse_context parse;
+   GLuint k;
+
+   mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0;
+   mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0;
+
+   if( mach->Processor == TGSI_PROCESSOR_GEOMETRY ) {
+      mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0] = 0;
+      mach->Primitives[0] = 0;
+   }
+
+   k = tgsi_parse_init( &parse, mach->Tokens );
+   if (k != TGSI_PARSE_OK) {
+      printf("Problem parsing!\n");
+      return;
+   }
+
+   while( !tgsi_parse_end_of_tokens( &parse ) ) {
+      tgsi_parse_token( &parse );
+      switch( parse.FullToken.Token.Type ) {
+      case TGSI_TOKEN_TYPE_DECLARATION:
+         break;
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+         break;
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+         exec_instruction( mach, &parse.FullToken.FullInstruction, labels, &parse.Position );
+         break;
+      default:
+         assert( 0 );
+      }
+   }
+   tgsi_parse_free (&parse);
+#endif
+
+#if MESA
+   if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) {
+      /*
+       * Scale back depth component.
+       */
+      for (i = 0; i < 4; i++)
+         mach->Outputs[0].xyzw[2].f[i] *= ctx->DrawBuffer->_DepthMaxF;
+   }
+#endif
+}
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_exec.h b/src/mesa/pipe/tgsi/core/tgsi_exec.h
new file mode 100644 (file)
index 0000000..abce6ee
--- /dev/null
@@ -0,0 +1,137 @@
+#if !defined TGSI_EXEC_H
+#define TGSI_EXEC_H
+
+#if 0
+#include "x86/rtasm/x86sse.h"
+#endif
+
+#if defined __cplusplus
+extern "C" {
+#endif // defined __cplusplus
+
+union tgsi_exec_channel
+{
+   GLfloat  f[4];
+   GLint    i[4];
+   GLuint   u[4];
+};
+
+struct tgsi_exec_vector
+{
+   union tgsi_exec_channel xyzw[4];
+};
+
+struct tgsi_sampler_state
+{
+    GLboolean   NeedLambda;
+    GLboolean   NeedLodBias;        /* if NeedLambda */
+    GLboolean   NeedLambdaClamp;    /* if NeedLambda */
+    GLfloat     LodBias;            /* if NeedLodBias */
+    GLfloat     MinLod;             /* if NeedLambdaClamp */
+    GLfloat     MaxLod;             /* if NeedLambdaClamp */
+    GLfloat     ImageWidth;
+    GLfloat     ImageHeight;
+    GLfloat     ImageDepth;
+};
+
+struct tgsi_exec_labels
+{
+   GLuint   labels[128][2];
+   GLuint   count;
+};
+
+#define TGSI_EXEC_TEMP_00000000_I   32
+#define TGSI_EXEC_TEMP_00000000_C   0
+
+#define TGSI_EXEC_TEMP_7FFFFFFF_I   32
+#define TGSI_EXEC_TEMP_7FFFFFFF_C   1
+
+#define TGSI_EXEC_TEMP_80000000_I   32
+#define TGSI_EXEC_TEMP_80000000_C   2
+
+#define TGSI_EXEC_TEMP_FFFFFFFF_I   32
+#define TGSI_EXEC_TEMP_FFFFFFFF_C   3
+
+#define TGSI_EXEC_TEMP_ONE_I        33
+#define TGSI_EXEC_TEMP_ONE_C        0
+
+#define TGSI_EXEC_TEMP_TWO_I        33
+#define TGSI_EXEC_TEMP_TWO_C        1
+
+#define TGSI_EXEC_TEMP_128_I        33
+#define TGSI_EXEC_TEMP_128_C        2
+
+#define TGSI_EXEC_TEMP_MINUS_128_I  33
+#define TGSI_EXEC_TEMP_MINUS_128_C  3
+
+#define TGSI_EXEC_TEMP_KILMASK_I    34
+#define TGSI_EXEC_TEMP_KILMASK_C    0
+
+#define TGSI_EXEC_TEMP_OUTPUT_I     34
+#define TGSI_EXEC_TEMP_OUTPUT_C     1
+
+#define TGSI_EXEC_TEMP_PRIMITIVE_I  34
+#define TGSI_EXEC_TEMP_PRIMITIVE_C  2
+
+#define TGSI_EXEC_TEMP_R0           35
+
+#define TGSI_EXEC_NUM_TEMPS   (32 + 4)
+#define TGSI_EXEC_NUM_ADDRS   1
+
+struct tgsi_exec_machine
+{
+   /*
+    * 32 program temporaries
+    * 4  internal temporaries
+    * 1  address
+    * 1  temporary of padding to align to 16 bytes
+    */
+   struct tgsi_exec_vector       _Temps[TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_ADDRS + 1];
+
+   /*
+    * This will point to _Temps after aligning to 16B boundary.
+    */
+   struct tgsi_exec_vector       *Temps;
+   struct tgsi_exec_vector       *Addrs;
+
+   struct tgsi_sampler_state     Samplers[16];
+
+   GLfloat                       Imms[256][4];
+   GLuint                        ImmLimit;
+   GLfloat                       (*Consts)[4];
+   const struct tgsi_exec_vector *Inputs;
+   struct tgsi_exec_vector       *Outputs;
+   struct tgsi_token             *Tokens;
+   GLuint                        Processor;
+
+   GLuint                        *Primitives;
+#if XXX_SSE
+   struct x86_function           Function;
+#endif
+};
+
+void
+tgsi_exec_machine_init(
+   struct tgsi_exec_machine *mach,
+   struct tgsi_token *tokens );
+
+void
+tgsi_exec_prepare(
+   struct tgsi_exec_machine *mach,
+   struct tgsi_exec_labels *labels );
+
+void
+tgsi_exec_machine_run(
+   struct tgsi_exec_machine *mach );
+
+void
+tgsi_exec_machine_run2(
+   struct tgsi_exec_machine *mach,
+   struct tgsi_exec_labels *labels );
+
+#if defined __cplusplus
+} // extern "C"
+#endif // defined __cplusplus
+
+#endif // !defined TGSI_EXEC_H
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_parse.c b/src/mesa/pipe/tgsi/core/tgsi_parse.c
new file mode 100644 (file)
index 0000000..df34fa7
--- /dev/null
@@ -0,0 +1,284 @@
+#include "tgsi_platform.h"
+#include "tgsi_core.h"
+
+void
+tgsi_full_token_init(
+   union tgsi_full_token *full_token )
+{
+   full_token->Token.Type = TGSI_TOKEN_TYPE_DECLARATION;
+}
+
+void
+tgsi_full_token_free(
+   union tgsi_full_token *full_token )
+{
+   if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE )
+      free( full_token->FullImmediate.u.Pointer );
+}
+
+GLuint
+tgsi_parse_init(
+   struct tgsi_parse_context *ctx,
+   const struct tgsi_token *tokens )
+{
+   ctx->FullVersion.Version = *(struct tgsi_version *) &tokens[0];
+   if( ctx->FullVersion.Version.MajorVersion > 1 ) {
+      return TGSI_PARSE_ERROR;
+   }
+
+   ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[1];
+   if( ctx->FullHeader.Header.HeaderSize >= 2 ) {
+      ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[2];
+   }
+   else {
+      ctx->FullHeader.Processor = tgsi_default_processor();
+   }
+
+   ctx->Tokens = tokens;
+   ctx->Position = 1 + ctx->FullHeader.Header.HeaderSize;
+
+   tgsi_full_token_init( &ctx->FullToken );
+
+   return TGSI_PARSE_OK;
+}
+
+void
+tgsi_parse_free(
+   struct tgsi_parse_context *ctx )
+{
+   tgsi_full_token_free( &ctx->FullToken );
+}
+
+GLuint
+tgsi_parse_end_of_tokens(
+   struct tgsi_parse_context *ctx )
+{
+   return ctx->Position >=
+      1 + ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize;
+}
+
+static void
+next_token(
+   struct tgsi_parse_context *ctx,
+   void *token )
+{
+   assert( !tgsi_parse_end_of_tokens( ctx ) );
+
+   *(struct tgsi_token *) token = ctx->Tokens[ctx->Position++];
+}
+
+void
+tgsi_parse_token(
+   struct tgsi_parse_context *ctx )
+{
+   struct tgsi_token token;
+   GLuint i;
+
+   tgsi_full_token_free( &ctx->FullToken );
+   tgsi_full_token_init( &ctx->FullToken );
+
+   next_token( ctx, &token );
+
+   switch( token.Type ) {
+   case TGSI_TOKEN_TYPE_DECLARATION:
+   {
+      struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration;
+
+      *decl = tgsi_default_full_declaration();
+      decl->Declaration = *(struct tgsi_declaration *) &token;
+
+      switch( decl->Declaration.Type ) {
+      case TGSI_DECLARE_RANGE:
+         next_token( ctx, &decl->u.DeclarationRange );
+         break;
+
+      case TGSI_DECLARE_MASK:
+         next_token( ctx, &decl->u.DeclarationMask );
+         break;
+
+      default:
+         assert (0);
+      }
+
+      if( decl->Declaration.Interpolate ) {
+         next_token( ctx, &decl->Interpolation );
+      }
+
+      break;
+   }
+
+   case TGSI_TOKEN_TYPE_IMMEDIATE:
+   {
+      struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate;
+
+      *imm = tgsi_default_full_immediate();
+      imm->Immediate = *(struct tgsi_immediate *) &token;
+
+      assert( !imm->Immediate.Extended );
+
+      switch (imm->Immediate.DataType) {
+      case TGSI_IMM_FLOAT32:
+         imm->u.Pointer = malloc(
+            sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.Size - 1) );
+         for( i = 0; i < imm->Immediate.Size - 1; i++ ) {
+            next_token( ctx, &imm->u.ImmediateFloat32[i] );
+         }
+         break;
+
+      default:
+         assert( 0 );
+      }
+
+      break;
+   }
+
+   case TGSI_TOKEN_TYPE_INSTRUCTION:
+   {
+      struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction;
+      GLuint extended;
+
+      *inst = tgsi_default_full_instruction();
+      inst->Instruction = *(struct tgsi_instruction *) &token;
+
+      extended = inst->Instruction.Extended;
+
+      while( extended ) {
+         struct tgsi_src_register_ext token;
+
+         next_token( ctx, &token );
+
+         switch( token.Type ) {
+         case TGSI_INSTRUCTION_EXT_TYPE_NV:
+            inst->InstructionExtNv =
+               *(struct tgsi_instruction_ext_nv *) &token;
+            break;
+
+         case TGSI_INSTRUCTION_EXT_TYPE_LABEL:
+            inst->InstructionExtLabel =
+               *(struct tgsi_instruction_ext_label *) &token;
+            break;
+
+         case TGSI_INSTRUCTION_EXT_TYPE_TEXTURE:
+            inst->InstructionExtTexture =
+               *(struct tgsi_instruction_ext_texture *) &token;
+            break;
+
+         default:
+            assert( 0 );
+         }
+
+         extended = token.Extended;
+      }
+
+      assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );
+
+      for(  i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
+         GLuint extended;
+
+         next_token( ctx, &inst->FullDstRegisters[i].DstRegister );
+
+         /*
+          * No support for indirect or multi-dimensional addressing.
+          */
+         assert( !inst->FullDstRegisters[i].DstRegister.Indirect );
+         assert( !inst->FullDstRegisters[i].DstRegister.Dimension );
+
+         extended = inst->FullDstRegisters[i].DstRegister.Extended;
+
+         while( extended ) {
+            struct tgsi_src_register_ext token;
+
+            next_token( ctx, &token );
+
+            switch( token.Type ) {
+            case TGSI_DST_REGISTER_EXT_TYPE_CONDCODE:
+               inst->FullDstRegisters[i].DstRegisterExtConcode =
+                  *(struct tgsi_dst_register_ext_concode *) &token;
+               break;
+
+            case TGSI_DST_REGISTER_EXT_TYPE_MODULATE:
+               inst->FullDstRegisters[i].DstRegisterExtModulate =
+                  *(struct tgsi_dst_register_ext_modulate *) &token;
+               break;
+
+            default:
+               assert( 0 );
+            }
+
+            extended = token.Extended;
+         }
+      }
+
+      assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS );
+
+      for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
+         GLuint extended;
+
+         next_token( ctx, &inst->FullSrcRegisters[i].SrcRegister );
+
+         extended = inst->FullSrcRegisters[i].SrcRegister.Extended;
+
+         while( extended ) {
+            struct tgsi_src_register_ext token;
+
+            next_token( ctx, &token );
+
+            switch( token.Type ) {
+            case TGSI_SRC_REGISTER_EXT_TYPE_SWZ:
+               inst->FullSrcRegisters[i].SrcRegisterExtSwz =
+                  *(struct tgsi_src_register_ext_swz *) &token;
+               break;
+
+            case TGSI_SRC_REGISTER_EXT_TYPE_MOD:
+               inst->FullSrcRegisters[i].SrcRegisterExtMod =
+                  *(struct tgsi_src_register_ext_mod *) &token;
+               break;
+
+            default:
+               assert( 0 );
+            }
+
+            extended = token.Extended;
+         }
+
+         if( inst->FullSrcRegisters[i].SrcRegister.Indirect ) {
+            next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterInd );
+
+            /*
+             * No support for indirect or multi-dimensional addressing.
+             */
+            assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect );
+            assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension );
+            assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended );
+         }
+
+         if( inst->FullSrcRegisters[i].SrcRegister.Dimension ) {
+            next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDim );
+
+            /*
+             * No support for multi-dimensional addressing.
+             */
+            assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Dimension );
+            assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Extended );
+
+            if( inst->FullSrcRegisters[i].SrcRegisterDim.Indirect ) {
+               next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDimInd );
+
+               /*
+               * No support for indirect or multi-dimensional addressing.
+               */
+               assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect );
+               assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension );
+               assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended );
+            }
+         }
+      }
+
+      break;
+   }
+
+   default:
+      assert( 0 );
+   }
+}
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_parse.h b/src/mesa/pipe/tgsi/core/tgsi_parse.h
new file mode 100644 (file)
index 0000000..61ad066
--- /dev/null
@@ -0,0 +1,120 @@
+#if !defined TGSI_PARSE_H
+#define TGSI_PARSE_H
+
+#if defined __cplusplus
+extern "C" {
+#endif // defined __cplusplus
+
+struct tgsi_full_version
+{
+   struct tgsi_version  Version;
+};
+
+struct tgsi_full_header
+{
+   struct tgsi_header      Header;
+   struct tgsi_processor   Processor;
+};
+
+struct tgsi_full_dst_register
+{
+   struct tgsi_dst_register               DstRegister;
+   struct tgsi_dst_register_ext_concode   DstRegisterExtConcode;
+   struct tgsi_dst_register_ext_modulate  DstRegisterExtModulate;
+};
+
+struct tgsi_full_src_register
+{
+   struct tgsi_src_register         SrcRegister;
+   struct tgsi_src_register_ext_swz SrcRegisterExtSwz;
+   struct tgsi_src_register_ext_mod SrcRegisterExtMod;
+   struct tgsi_src_register         SrcRegisterInd;
+   struct tgsi_dimension            SrcRegisterDim;
+   struct tgsi_src_register         SrcRegisterDimInd;
+};
+
+struct tgsi_full_declaration
+{
+   struct tgsi_declaration Declaration;
+   union
+   {
+      struct tgsi_declaration_range DeclarationRange;
+      struct tgsi_declaration_mask  DeclarationMask;
+   } u;
+   struct tgsi_declaration_interpolation  Interpolation;
+};
+
+struct tgsi_full_immediate
+{
+   struct tgsi_immediate   Immediate;
+   union
+   {
+      void                          *Pointer;
+      struct tgsi_immediate_float32 *ImmediateFloat32;
+   } u;
+};
+
+#define TGSI_FULL_MAX_DST_REGISTERS 2
+#define TGSI_FULL_MAX_SRC_REGISTERS 3
+
+struct tgsi_full_instruction
+{
+   struct tgsi_instruction             Instruction;
+   struct tgsi_instruction_ext_nv      InstructionExtNv;
+   struct tgsi_instruction_ext_label   InstructionExtLabel;
+   struct tgsi_instruction_ext_texture InstructionExtTexture;
+   struct tgsi_full_dst_register       FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS];
+   struct tgsi_full_src_register       FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS];
+};
+
+union tgsi_full_token
+{
+   struct tgsi_token             Token;
+   struct tgsi_full_declaration  FullDeclaration;
+   struct tgsi_full_immediate    FullImmediate;
+   struct tgsi_full_instruction  FullInstruction;
+};
+
+void
+tgsi_full_token_init(
+   union tgsi_full_token *full_token );
+
+void
+tgsi_full_token_free(
+   union tgsi_full_token *full_token );
+
+struct tgsi_parse_context
+{
+   const struct tgsi_token    *Tokens;
+   GLuint                     Position;
+   struct tgsi_full_version   FullVersion;
+   struct tgsi_full_header    FullHeader;
+   union tgsi_full_token      FullToken;
+};
+
+#define TGSI_PARSE_OK      0
+#define TGSI_PARSE_ERROR   1
+
+GLuint
+tgsi_parse_init(
+   struct tgsi_parse_context *ctx,
+   const struct tgsi_token *tokens );
+
+void
+tgsi_parse_free(
+   struct tgsi_parse_context *ctx );
+
+GLuint
+tgsi_parse_end_of_tokens(
+   struct tgsi_parse_context *ctx );
+
+void
+tgsi_parse_token(
+   struct tgsi_parse_context *ctx );
+
+#if defined __cplusplus
+} // extern "C"
+#endif // defined __cplusplus
+
+#endif // !defined TGSI_PARSE_H
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_token.h b/src/mesa/pipe/tgsi/core/tgsi_token.h
new file mode 100644 (file)
index 0000000..becdd48
--- /dev/null
@@ -0,0 +1,1045 @@
+#if !defined TGSI_TOKEN_H
+#define TGSI_TOKEN_H
+
+#if defined __cplusplus
+extern "C" {
+#endif // defined __cplusplus
+
+struct tgsi_version
+{
+   GLuint MajorVersion  : 8;
+   GLuint MinorVersion  : 8;
+   GLuint Padding       : 16;
+};
+
+struct tgsi_header
+{
+   GLuint HeaderSize : 8;
+   GLuint BodySize   : 24;
+};
+
+#define TGSI_PROCESSOR_FRAGMENT  0
+#define TGSI_PROCESSOR_VERTEX    1
+#define TGSI_PROCESSOR_GEOMETRY  2
+
+struct tgsi_processor
+{
+   GLuint Processor  : 4;  /* TGSI_PROCESSOR_ */
+   GLuint Padding    : 28;
+};
+
+#define TGSI_TOKEN_TYPE_DECLARATION    0
+#define TGSI_TOKEN_TYPE_IMMEDIATE      1
+#define TGSI_TOKEN_TYPE_INSTRUCTION    2
+
+struct tgsi_token
+{
+   GLuint Type       : 4;  /* TGSI_TOKEN_TYPE_ */
+   GLuint Size       : 8;  /* UINT */
+   GLuint Padding    : 19;
+   GLuint Extended   : 1;  /* BOOL */
+};
+
+#define TGSI_FILE_NULL        0
+#define TGSI_FILE_CONSTANT    1
+#define TGSI_FILE_INPUT       2
+#define TGSI_FILE_OUTPUT      3
+#define TGSI_FILE_TEMPORARY   4
+#define TGSI_FILE_SAMPLER     5
+#define TGSI_FILE_ADDRESS     6
+#define TGSI_FILE_IMMEDIATE   7
+
+#define TGSI_DECLARE_RANGE    0
+#define TGSI_DECLARE_MASK     1
+
+struct tgsi_declaration
+{
+   GLuint Type          : 4;  /* TGSI_TOKEN_TYPE_DECLARATION */
+   GLuint Size          : 8;  /* UINT */
+   GLuint File          : 4;  /* TGSI_FILE_ */
+   GLuint Declare       : 4;  /* TGSI_DECLARE_ */
+   GLuint Interpolate   : 1;  /* BOOL */
+   GLuint Padding       : 10;
+   GLuint Extended      : 1;  /* BOOL */
+};
+
+struct tgsi_declaration_range
+{
+   GLuint First   : 16; /* UINT */
+   GLuint Last    : 16; /* UINT */
+};
+
+struct tgsi_declaration_mask
+{
+   GLuint Mask : 32; /* UINT */
+};
+
+#define TGSI_INTERPOLATE_CONSTANT      0
+#define TGSI_INTERPOLATE_LINEAR        1
+#define TGSI_INTERPOLATE_PERSPECTIVE   2
+
+struct tgsi_declaration_interpolation
+{
+   GLuint Interpolate   : 4;  /* TGSI_INTERPOLATE_ */
+   GLuint Padding       : 28;
+};
+
+#define TGSI_IMM_FLOAT32   0
+
+struct tgsi_immediate
+{
+   GLuint Type       : 4;  /* TGSI_TOKEN_TYPE_IMMEDIATE */
+   GLuint Size       : 8;  /* UINT */
+   GLuint DataType   : 4;  /* TGSI_IMM_ */
+   GLuint Padding    : 15;
+   GLuint Extended   : 1;  /* BOOL */
+};
+
+struct tgsi_immediate_float32
+{
+   GLfloat Float;
+};
+
+/*
+ * GL_NV_vertex_program
+ */
+#define TGSI_OPCODE_ARL                 0
+#define TGSI_OPCODE_MOV                 1
+#define TGSI_OPCODE_LIT                 2
+#define TGSI_OPCODE_RCP                 3
+#define TGSI_OPCODE_RSQ                 4
+#define TGSI_OPCODE_EXP                 5
+#define TGSI_OPCODE_LOG                 6
+#define TGSI_OPCODE_MUL                 7
+#define TGSI_OPCODE_ADD                 8
+#define TGSI_OPCODE_DP3                 9
+#define TGSI_OPCODE_DP4                 10
+#define TGSI_OPCODE_DST                 11
+#define TGSI_OPCODE_MIN                 12
+#define TGSI_OPCODE_MAX                 13
+#define TGSI_OPCODE_SLT                 14
+#define TGSI_OPCODE_SGE                 15
+#define TGSI_OPCODE_MAD                 16
+
+/*
+ * GL_ATI_fragment_shader
+ */
+/* TGSI_OPCODE_MOV */
+/* TGSI_OPCODE_ADD */
+/* TGSI_OPCODE_MUL */
+#define TGSI_OPCODE_SUB                 17
+#define TGSI_OPCODE_DOT3                TGSI_OPCODE_DP3
+#define TGSI_OPCODE_DOT4                TGSI_OPCODE_DP4
+/* TGSI_OPCODE_MAD */
+#define TGSI_OPCODE_LERP                18
+#define TGSI_OPCODE_CND                 19
+#define TGSI_OPCODE_CND0                20
+#define TGSI_OPCODE_DOT2ADD             21
+
+/*
+ * GL_EXT_vertex_shader
+ */
+#define TGSI_OPCODE_INDEX               22
+#define TGSI_OPCODE_NEGATE              23
+/* TGSI_OPCODE_DOT3 */
+/* TGSI_OPCODE_DOT4 */
+/* TGSI_OPCODE_MUL */
+/* TGSI_OPCODE_ADD */
+#define TGSI_OPCODE_MADD                TGSI_OPCODE_MAD
+#define TGSI_OPCODE_FRAC                24
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_MIN */
+#define TGSI_OPCODE_SETGE               TGSI_OPCODE_SGE
+#define TGSI_OPCODE_SETLT               TGSI_OPCODE_SLT
+#define TGSI_OPCODE_CLAMP               25
+#define TGSI_OPCODE_FLOOR               26
+#define TGSI_OPCODE_ROUND               27
+#define TGSI_OPCODE_EXPBASE2            28
+#define TGSI_OPCODE_LOGBASE2            29
+#define TGSI_OPCODE_POWER               30
+#define TGSI_OPCODE_RECIP               TGSI_OPCODE_RCP
+#define TGSI_OPCODE_RECIPSQRT           TGSI_OPCODE_RSQ
+/* TGSI_OPCODE_SUB */
+#define TGSI_OPCODE_CROSSPRODUCT        31
+#define TGSI_OPCODE_MULTIPLYMATRIX      32
+/* TGSI_OPCODE_MOV */
+
+/*
+ * GL_NV_vertex_program1_1
+ */
+/* TGSI_OPCODE_ARL */
+/* TGSI_OPCODE_MOV */
+/* TGSI_OPCODE_LIT */
+#define TGSI_OPCODE_ABS                 33
+/* TGSI_OPCODE_RCP */
+/* TGSI_OPCODE_RSQ */
+/* TGSI_OPCODE_EXP */
+/* TGSI_OPCODE_LOG */
+#define TGSI_OPCODE_RCC                 34
+/* TGSI_OPCODE_MUL */
+/* TGSI_OPCODE_ADD */
+/* TGSI_OPCODE_DP3 */
+/* TGSI_OPCODE_DP4 */
+/* TGSI_OPCODE_DST */
+/* TGSI_OPCODE_MIN */
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_SLT */
+/* TGSI_OPCODE_SGE */
+#define TGSI_OPCODE_DPH                 35
+/* TGSI_OPCODE_SUB */
+/* TGSI_OPCODE_MAD */
+
+/*
+ * GL_NV_fragment_program
+ */
+/* TGSI_OPCODE_ADD */
+#define TGSI_OPCODE_COS                 36
+#define TGSI_OPCODE_DDX                 37
+#define TGSI_OPCODE_DDY                 38
+/* TGSI_OPCODE_DP3 */
+/* TGSI_OPCODE_DP4 */
+/* TGSI_OPCODE_DST */
+#define TGSI_OPCODE_EX2                 TGSI_OPCODE_EXPBASE2
+#define TGSI_OPCODE_FLR                 TGSI_OPCODE_FLOOR
+#define TGSI_OPCODE_FRC                 TGSI_OPCODE_FRAC
+#define TGSI_OPCODE_KIL                 39
+#define TGSI_OPCODE_LG2                 TGSI_OPCODE_LOGBASE2
+/* TGSI_OPCODE_LIT */
+#define TGSI_OPCODE_LRP                 TGSI_OPCODE_LERP
+/* TGSI_OPCODE_MAD */
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_MIN */
+/* TGSI_OPCODE_MOV */
+/* TGSI_OPCODE_MUL */
+#define TGSI_OPCODE_PK2H                40
+#define TGSI_OPCODE_PK2US               41
+#define TGSI_OPCODE_PK4B                42
+#define TGSI_OPCODE_PK4UB               43
+#define TGSI_OPCODE_POW                 TGSI_OPCODE_POWER
+/* TGSI_OPCODE_RCP */
+#define TGSI_OPCODE_RFL                 44
+/* TGSI_OPCODE_RSQ */
+#define TGSI_OPCODE_SEQ                 45
+#define TGSI_OPCODE_SFL                 46
+/* TGSI_OPCODE_SGE */
+#define TGSI_OPCODE_SGT                 47
+#define TGSI_OPCODE_SIN                 48
+#define TGSI_OPCODE_SLE                 49
+/* TGSI_OPCODE_SLT */
+#define TGSI_OPCODE_SNE                 50
+#define TGSI_OPCODE_STR                 51
+/* TGSI_OPCODE_SUB */
+#define TGSI_OPCODE_TEX                 52
+#define TGSI_OPCODE_TXD                 53
+/* TGSI_OPCODE_TXP - use TGSI_OPCODE_TEX */
+#define TGSI_OPCODE_UP2H                54
+#define TGSI_OPCODE_UP2US               55
+#define TGSI_OPCODE_UP4B                56
+#define TGSI_OPCODE_UP4UB               57
+#define TGSI_OPCODE_X2D                 58
+
+/*
+ * GL_NV_vertex_program2
+ */
+/* TGSI_OPCODE_ABS */
+/* TGSI_OPCODE_ADD */
+#define TGSI_OPCODE_ARA                 59
+/* TGSI_OPCODE_ARL */
+#define TGSI_OPCODE_ARR                 60
+#define TGSI_OPCODE_BRA                 61
+#define TGSI_OPCODE_CAL                 62
+/* TGSI_OPCODE_COS */
+/* TGSI_OPCODE_DP3 */
+/* TGSI_OPCODE_DP4 */
+/* TGSI_OPCODE_DPH */
+/* TGSI_OPCODE_DST */
+/* TGSI_OPCODE_EX2 */
+/* TGSI_OPCODE_EXP */
+/* TGSI_OPCODE_FLR */
+/* TGSI_OPCODE_FRC */
+/* TGSI_OPCODE_LG2 */
+/* TGSI_OPCODE_LIT */
+/* TGSI_OPCODE_LOG */
+/* TGSI_OPCODE_MAD */
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_MIN */
+/* TGSI_OPCODE_MOV */
+/* TGSI_OPCODE_MUL */
+/* TGSI_OPCODE_RCC */
+/* TGSI_OPCODE_RCP */
+#define TGSI_OPCODE_RET                 63
+/* TGSI_OPCODE_RSQNV */
+/* TGSI_OPCODE_SEQ */
+/* TGSI_OPCODE_SFL */
+/* TGSI_OPCODE_SGE */
+/* TGSI_OPCODE_SGT */
+/* TGSI_OPCODE_SIN */
+/* TGSI_OPCODE_SLE */
+/* TGSI_OPCODE_SLT */
+/* TGSI_OPCODE_SNE */
+#define TGSI_OPCODE_SSG                 64
+/* TGSI_OPCODE_STR */
+/* TGSI_OPCODE_SUB */
+
+/*
+ * GL_ARB_vertex_program
+ */
+/* TGSI_OPCODE_ABS */
+/* TGSI_OPCODE_ADD */
+/* TGSI_OPCODE_ARL */
+/* TGSI_OPCODE_DP3 */
+/* TGSI_OPCODE_DP4 */
+/* TGSI_OPCODE_DPH */
+/* TGSI_OPCODE_DST */
+/* TGSI_OPCODE_EX2 */
+/* TGSI_OPCODE_EXP */
+/* TGSI_OPCODE_FLR */
+/* TGSI_OPCODE_FRC */
+/* TGSI_OPCODE_LG2 */
+/* TGSI_OPCODE_LIT */
+/* TGSI_OPCODE_LOG */
+/* TGSI_OPCODE_MAD */
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_MIN */
+/* TGSI_OPCODE_MOV */
+/* TGSI_OPCODE_MUL */
+/* TGSI_OPCODE_POW */
+/* TGSI_OPCODE_RCP */
+/* TGSI_OPCODE_RSQ */
+/* TGSI_OPCODE_SGE */
+/* TGSI_OPCODE_SLT */
+/* TGSI_OPCODE_SUB */
+#define TGSI_OPCODE_SWZ                 TGSI_OPCODE_MOV
+#define TGSI_OPCODE_XPD                 TGSI_OPCODE_CROSSPRODUCT
+
+/*
+ * GL_ARB_fragment_program
+ */
+/* TGSI_OPCODE_ABS */
+/* TGSI_OPCODE_ADD */
+#define TGSI_OPCODE_CMP                 65
+/* TGSI_OPCODE_COS */
+/* TGSI_OPCODE_DP3 */
+/* TGSI_OPCODE_DP4 */
+/* TGSI_OPCODE_DPH */
+/* TGSI_OPCODE_DST */
+/* TGSI_OPCODE_EX2 */
+/* TGSI_OPCODE_FLR */
+/* TGSI_OPCODE_FRC */
+/* TGSI_OPCODE_LG2 */
+/* TGSI_OPCODE_LIT */
+/* TGSI_OPCODE_LRP */
+/* TGSI_OPCODE_MAD */
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_MIN */
+/* TGSI_OPCODE_MOV */
+/* TGSI_OPCODE_MUL */
+/* TGSI_OPCODE_POW */
+/* TGSI_OPCODE_RCP */
+/* TGSI_OPCODE_RSQ */
+#define TGSI_OPCODE_SCS                 66
+/* TGSI_OPCODE_SGE */
+/* TGSI_OPCODE_SIN */
+/* TGSI_OPCODE_SLT */
+/* TGSI_OPCODE_SUB */
+/* TGSI_OPCODE_SWZ */
+/* TGSI_OPCODE_XPD */
+/* TGSI_OPCODE_TEX */
+/* TGSI_OPCODE_TXP */
+#define TGSI_OPCODE_TXB                 67
+/* TGSI_OPCODE_KIL */
+
+/*
+ * GL_NV_fragment_program_option
+ */
+/* TGSI_OPCODE_ABS */
+/* TGSI_OPCODE_FLR */
+/* TGSI_OPCODE_FRC */
+/* TGSI_OPCODE_LIT */
+/* TGSI_OPCODE_MOV */
+/* TGSI_OPCODE_DDX */
+/* TGSI_OPCODE_DDY */
+/* TGSI_OPCODE_PK2H */
+/* TGSI_OPCODE_PK2US */
+/* TGSI_OPCODE_PK4B */
+/* TGSI_OPCODE_PK4UB */
+/* TGSI_OPCODE_COS */
+/* TGSI_OPCODE_EX2 */
+/* TGSI_OPCODE_LG2 */
+/* TGSI_OPCODE_RCP */
+/* TGSI_OPCODE_RSQ */
+/* TGSI_OPCODE_SIN */
+/* TGSI_OPCODE_SCS */
+/* TGSI_OPCODE_UP2H */
+/* TGSI_OPCODE_UP2US */
+/* TGSI_OPCODE_UP4B */
+/* TGSI_OPCODE_UP4UB */
+/* TGSI_OPCODE_POW */
+/* TGSI_OPCODE_ADD */
+/* TGSI_OPCODE_DP3 */
+/* TGSI_OPCODE_DP4 */
+/* TGSI_OPCODE_DPH */
+/* TGSI_OPCODE_DST */
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_MIN */
+/* TGSI_OPCODE_MUL */
+/* TGSI_OPCODE_SGE */
+/* TGSI_OPCODE_SLT */
+/* TGSI_OPCODE_SUB */
+/* TGSI_OPCODE_XPD */
+/* TGSI_OPCODE_RFL */
+/* TGSI_OPCODE_SEQ */
+/* TGSI_OPCODE_SFL */
+/* TGSI_OPCODE_SGT */
+/* TGSI_OPCODE_SLE */
+/* TGSI_OPCODE_SNE */
+/* TGSI_OPCODE_STR */
+/* TGSI_OPCODE_CMP */
+/* TGSI_OPCODE_LRP */
+/* TGSI_OPCODE_MAD */
+/* TGSI_OPCODE_X2D */
+/* TGSI_OPCODE_SWZ */
+/* TGSI_OPCODE_TEX */
+/* TGSI_OPCODE_TXP */
+/* TGSI_OPCODE_TXB */
+/* TGSI_OPCODE_KIL */
+/* TGSI_OPCODE_TXD */
+
+/*
+ * GL_NV_fragment_program2
+ */
+/* TGSI_OPCODE_ABS */
+/* TGSI_OPCODE_FLR */
+/* TGSI_OPCODE_FRC */
+/* TGSI_OPCODE_LIT */
+/* TGSI_OPCODE_MOV */
+/* TGSI_OPCODE_DDX */
+/* TGSI_OPCODE_DDY */
+/* TGSI_OPCODE_PK2H */
+/* TGSI_OPCODE_PK2US */
+/* TGSI_OPCODE_PK4B */
+/* TGSI_OPCODE_PK4UB */
+#define TGSI_OPCODE_NRM                 68
+#define TGSI_OPCODE_DIV                 69
+/* TGSI_OPCODE_COS */
+/* TGSI_OPCODE_EX2 */
+/* TGSI_OPCODE_LG2 */
+/* TGSI_OPCODE_RCP */
+/* TGSI_OPCODE_RSQ */
+/* TGSI_OPCODE_SIN */
+/* TGSI_OPCODE_SCS */
+/* TGSI_OPCODE_UP2H */
+/* TGSI_OPCODE_UP2US */
+/* TGSI_OPCODE_UP4B */
+/* TGSI_OPCODE_UP4UB */
+/* TGSI_OPCODE_POW */
+/* TGSI_OPCODE_ADD */
+/* TGSI_OPCODE_DP3 */
+/* TGSI_OPCODE_DP4 */
+/* TGSI_OPCODE_DPH */
+/* TGSI_OPCODE_DST */
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_MIN */
+/* TGSI_OPCODE_MUL */
+/* TGSI_OPCODE_SGE */
+/* TGSI_OPCODE_SLT */
+/* TGSI_OPCODE_SUB */
+/* TGSI_OPCODE_XPD */
+/* TGSI_OPCODE_RFL */
+/* TGSI_OPCODE_SEQ */
+/* TGSI_OPCODE_SFL */
+/* TGSI_OPCODE_SGT */
+/* TGSI_OPCODE_SLE */
+/* TGSI_OPCODE_SNE */
+/* TGSI_OPCODE_STR */
+#define TGSI_OPCODE_DP2                 70
+/* TGSI_OPCODE_CMP */
+/* TGSI_OPCODE_LRP */
+/* TGSI_OPCODE_MAD */
+/* TGSI_OPCODE_X2D */
+#define TGSI_OPCODE_DP2A                TGSI_OPCODE_DOT2ADD
+/* TGSI_OPCODE_SWZ */
+/* TGSI_OPCODE_TEX */
+/* TGSI_OPCODE_TXP */
+/* TGSI_OPCODE_TXB */
+#define TGSI_OPCODE_TXL                 71
+/* TGSI_OPCODE_KIL */
+/* TGSI_OPCODE_TXD */
+/* TGSI_OPCODE_CAL */
+/* TGSI_OPCODE_RET */
+#define TGSI_OPCODE_BRK                 72
+#define TGSI_OPCODE_IF                  73
+#define TGSI_OPCODE_LOOP                74
+#define TGSI_OPCODE_REP                 75
+#define TGSI_OPCODE_ELSE                76
+#define TGSI_OPCODE_ENDIF               77
+#define TGSI_OPCODE_ENDLOOP             78
+#define TGSI_OPCODE_ENDREP              79
+
+/*
+ * GL_NV_vertex_program2_option
+ */
+/* TGSI_OPCODE_ARL */
+/* TGSI_OPCODE_ABS */
+/* TGSI_OPCODE_FLR */
+/* TGSI_OPCODE_FRC */
+/* TGSI_OPCODE_LIT */
+/* TGSI_OPCODE_MOV */
+/* TGSI_OPCODE_SSG */
+/* TGSI_OPCODE_EX2 */
+/* TGSI_OPCODE_EXP */
+/* TGSI_OPCODE_LG2 */
+/* TGSI_OPCODE_LOG */
+/* TGSI_OPCODE_RCP */
+/* TGSI_OPCODE_RSQ */
+/* TGSI_OPCODE_COS */
+/* TGSI_OPCODE_RCC */
+/* TGSI_OPCODE_SIN */
+/* TGSI_OPCODE_POW */
+/* TGSI_OPCODE_ADD */
+/* TGSI_OPCODE_DP3 */
+/* TGSI_OPCODE_DP4 */
+/* TGSI_OPCODE_DPH */
+/* TGSI_OPCODE_DST */
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_MIN */
+/* TGSI_OPCODE_MUL */
+/* TGSI_OPCODE_SGE */
+/* TGSI_OPCODE_SLT */
+/* TGSI_OPCODE_SUB */
+/* TGSI_OPCODE_XPD */
+/* TGSI_OPCODE_SEQ */
+/* TGSI_OPCODE_SFL */
+/* TGSI_OPCODE_SGT */
+/* TGSI_OPCODE_SLE */
+/* TGSI_OPCODE_SNE */
+/* TGSI_OPCODE_STR */
+/* TGSI_OPCODE_MAD */
+/* TGSI_OPCODE_SWZ */
+/* TGSI_OPCODE_ARR */
+/* TGSI_OPCODE_ARA */
+/* TGSI_OPCODE_BRA */
+/* TGSI_OPCODE_CAL */
+/* TGSI_OPCODE_RET */
+
+/*
+ * GL_NV_vertex_program3
+ */
+/* TGSI_OPCODE_ARL */
+/* TGSI_OPCODE_ABS */
+/* TGSI_OPCODE_FLR */
+/* TGSI_OPCODE_FRC */
+/* TGSI_OPCODE_LIT */
+/* TGSI_OPCODE_MOV */
+/* TGSI_OPCODE_SSG */
+/* TGSI_OPCODE_EX2 */
+/* TGSI_OPCODE_EXP */
+/* TGSI_OPCODE_LG2 */
+/* TGSI_OPCODE_LOG */
+/* TGSI_OPCODE_RCP */
+/* TGSI_OPCODE_RSQ */
+/* TGSI_OPCODE_COS */
+/* TGSI_OPCODE_RCC */
+/* TGSI_OPCODE_SIN */
+/* TGSI_OPCODE_POW */
+/* TGSI_OPCODE_ADD */
+/* TGSI_OPCODE_DP3 */
+/* TGSI_OPCODE_DP4 */
+/* TGSI_OPCODE_DPH */
+/* TGSI_OPCODE_DST */
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_MIN */
+/* TGSI_OPCODE_MUL */
+/* TGSI_OPCODE_SGE */
+/* TGSI_OPCODE_SLT */
+/* TGSI_OPCODE_SUB */
+/* TGSI_OPCODE_XPD */
+/* TGSI_OPCODE_SEQ */
+/* TGSI_OPCODE_SFL */
+/* TGSI_OPCODE_SGT */
+/* TGSI_OPCODE_SLE */
+/* TGSI_OPCODE_SNE */
+/* TGSI_OPCODE_STR */
+/* TGSI_OPCODE_MAD */
+/* TGSI_OPCODE_SWZ */
+/* TGSI_OPCODE_ARR */
+/* TGSI_OPCODE_ARA */
+/* TGSI_OPCODE_BRA */
+/* TGSI_OPCODE_CAL */
+/* TGSI_OPCODE_RET */
+#define TGSI_OPCODE_PUSHA               80
+#define TGSI_OPCODE_POPA                81
+/* TGSI_OPCODE_TEX */
+/* TGSI_OPCODE_TXP */
+/* TGSI_OPCODE_TXB */
+/* TGSI_OPCODE_TXL */
+
+/*
+ * GL_NV_gpu_program4
+ */
+/* TGSI_OPCODE_ABS */
+#define TGSI_OPCODE_CEIL                82
+/* TGSI_OPCODE_FLR */
+/* TGSI_OPCODE_FRC */
+#define TGSI_OPCODE_I2F                 83
+/* TGSI_OPCODE_LIT */
+/* TGSI_OPCODE_MOV */
+#define TGSI_OPCODE_NOT                 84
+/* TGSI_OPCODE_NRM */
+/* TGSI_OPCODE_PK2H */
+/* TGSI_OPCODE_PK2US */
+/* TGSI_OPCODE_PK4B */
+/* TGSI_OPCODE_PK4UB */
+/* TGSI_OPCODE_ROUND */
+/* TGSI_OPCODE_SSG */
+#define TGSI_OPCODE_TRUNC               85
+/* TGSI_OPCODE_COS */
+/* TGSI_OPCODE_EX2 */
+/* TGSI_OPCODE_LG2 */
+/* TGSI_OPCODE_RCC */
+/* TGSI_OPCODE_RCP */
+/* TGSI_OPCODE_RSQ */
+/* TGSI_OPCODE_SCS */
+/* TGSI_OPCODE_SIN */
+/* TGSI_OPCODE_UP2H */
+/* TGSI_OPCODE_UP2US */
+/* TGSI_OPCODE_UP4B */
+/* TGSI_OPCODE_UP4UB */
+/* TGSI_OPCODE_POW */
+/* TGSI_OPCODE_DIV */
+#define TGSI_OPCODE_SHL                 86
+#define TGSI_OPCODE_SHR                 87
+/* TGSI_OPCODE_ADD */
+#define TGSI_OPCODE_AND                 88
+/* TGSI_OPCODE_DP3 */
+/* TGSI_OPCODE_DP4 */
+/* TGSI_OPCODE_DPH */
+/* TGSI_OPCODE_DST */
+/* TGSI_OPCODE_MAX */
+/* TGSI_OPCODE_MIN */
+/* TGSI_OPCODE_MUL */
+#define TGSI_OPCODE_OR                  89
+/* TGSI_OPCODE_RFL */
+/* TGSI_OPCODE_SEQ */
+/* TGSI_OPCODE_SFL */
+/* TGSI_OPCODE_SGE */
+/* TGSI_OPCODE_SGT */
+/* TGSI_OPCODE_SLE */
+/* TGSI_OPCODE_SLT */
+/* TGSI_OPCODE_SNE */
+/* TGSI_OPCODE_STR */
+/* TGSI_OPCODE_SUB */
+/* TGSI_OPCODE_XPD */
+/* TGSI_OPCODE_DP2 */
+#define TGSI_OPCODE_MOD                 90
+#define TGSI_OPCODE_XOR                 91
+/* TGSI_OPCODE_CMP */
+/* TGSI_OPCODE_DP2A */
+/* TGSI_OPCODE_LRP */
+/* TGSI_OPCODE_MAD */
+#define TGSI_OPCODE_SAD                 92
+/* TGSI_OPCODE_X2D */
+/* TGSI_OPCODE_SWZ */
+/* TGSI_OPCODE_TEX */
+/* TGSI_OPCODE_TXB */
+#define TGSI_OPCODE_TXF                 93
+/* TGSI_OPCODE_TXL */
+/* TGSI_OPCODE_TXP */
+#define TGSI_OPCODE_TXQ                 94
+/* TGSI_OPCODE_TXD */
+/* TGSI_OPCODE_CAL */
+/* TGSI_OPCODE_RET */
+/* TGSI_OPCODE_BRK */
+#define TGSI_OPCODE_CONT                95
+/* TGSI_OPCODE_IF */
+/* TGSI_OPCODE_REP */
+/* TGSI_OPCODE_ELSE */
+/* TGSI_OPCODE_ENDIF */
+/* TGSI_OPCODE_ENDREP */
+
+/*
+ * GL_NV_vertex_program4
+ */
+/* Same as GL_NV_gpu_program4 */
+
+/*
+ * GL_NV_fragment_program4
+ */
+/* Same as GL_NV_gpu_program4 */
+/* TGSI_OPCODE_KIL */
+/* TGSI_OPCODE_DDX */
+/* TGSI_OPCODE_DDY */
+
+/*
+ * GL_NV_geometry_program4
+ */
+/* Same as GL_NV_gpu_program4 */
+#define TGSI_OPCODE_EMIT                96
+#define TGSI_OPCODE_ENDPRIM             97
+
+#define TGSI_OPCODE_LAST                98
+
+#define TGSI_SAT_NONE            0  /* do not saturate */
+#define TGSI_SAT_ZERO_ONE        1  /* clamp to [0,1] */
+#define TGSI_SAT_MINUS_PLUS_ONE  2  /* clamp to [-1,1] */
+
+/*
+ * Opcode is the operation code to execute. A given operation defines the
+ * semantics how the source registers (if any) are interpreted and what is
+ * written to the destination registers (if any) as a result of execution.
+ *
+ * NumDstRegs and NumSrcRegs is the number of destination and source registers,
+ * respectively. For a given operation code, those numbers are fixed and are
+ * present here only for convenience.
+ *
+ * If Extended is TRUE, it is now executed.
+ *
+ * Saturate controls how are final results in destination registers modified.
+ */
+
+struct tgsi_instruction
+{
+   GLuint Type       : 4;  /* TGSI_TOKEN_TYPE_INSTRUCTION */
+   GLuint Size       : 8;  /* UINT */
+   GLuint Opcode     : 8;  /* TGSI_OPCODE_ */
+   GLuint Saturate   : 2;  /* TGSI_SAT_ */
+   GLuint NumDstRegs : 2;  /* UINT */
+   GLuint NumSrcRegs : 4;  /* UINT */
+   GLuint Padding    : 3;
+   GLuint Extended   : 1;  /* BOOL */
+};
+
+/*
+ * If tgsi_instruction::Extended is TRUE, tgsi_instruction_ext follows.
+ * 
+ * Then, tgsi_instruction::NumDstRegs of tgsi_dst_register follow.
+ * 
+ * Then, tgsi_instruction::NumSrcRegs of tgsi_src_register follow.
+ *
+ * tgsi_instruction::Size contains the total number of words that make the
+ * instruction, including the instruction word.
+ */
+
+#define TGSI_INSTRUCTION_EXT_TYPE_NV        0
+#define TGSI_INSTRUCTION_EXT_TYPE_LABEL     1
+#define TGSI_INSTRUCTION_EXT_TYPE_TEXTURE   2
+
+struct tgsi_instruction_ext
+{
+   GLuint Type       : 4;  /* TGSI_INSTRUCTION_EXT_TYPE_ */
+   GLuint Padding    : 27;
+   GLuint Extended   : 1;  /* BOOL */
+};
+
+/*
+ * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_NV, it should
+ * be cast to tgsi_instruction_ext_nv.
+ * 
+ * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_LABEL, it
+ * should be cast to tgsi_instruction_ext_label.
+ * 
+ * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_TEXTURE, it
+ * should be cast to tgsi_instruction_ext_texture.
+ * 
+ * If tgsi_instruction_ext::Extended is TRUE, another tgsi_instruction_ext
+ * follows.
+ */
+
+#define TGSI_PRECISION_DEFAULT      0
+#define TGSI_PRECISION_FLOAT32      1
+#define TGSI_PRECISION_FLOAT16      2
+#define TGSI_PRECISION_FIXED12      3
+
+#define TGSI_CC_GT      0
+#define TGSI_CC_EQ      1
+#define TGSI_CC_LT      2
+#define TGSI_CC_UN      3
+#define TGSI_CC_GE      4
+#define TGSI_CC_LE      5
+#define TGSI_CC_NE      6
+#define TGSI_CC_TR      7
+#define TGSI_CC_FL      8
+
+#define TGSI_SWIZZLE_X      0
+#define TGSI_SWIZZLE_Y      1
+#define TGSI_SWIZZLE_Z      2
+#define TGSI_SWIZZLE_W      3
+
+/*
+ * Precision controls the precision at which the operation should be executed.
+ *
+ * CondDstUpdate enables condition code register writes. When this field is
+ * TRUE, CondDstIndex specifies the index of the condition code register to
+ * update.
+ *
+ * CondFlowEnable enables conditional execution of the operation. When this
+ * field is TRUE, CondFlowIndex specifies the index of the condition code
+ * register to test against CondMask with component swizzle controled by
+ * CondSwizzleX, CondSwizzleY, CondSwizzleZ and CondSwizzleW. If the test fails,
+ * the operation is not executed.
+ */
+
+struct tgsi_instruction_ext_nv
+{
+   GLuint Type             : 4;    /* TGSI_INSTRUCTION_EXT_TYPE_NV */
+   GLuint Precision        : 4;    /* TGSI_PRECISION_ */
+   GLuint CondDstIndex     : 4;    /* UINT */
+   GLuint CondFlowIndex    : 4;    /* UINT */
+   GLuint CondMask         : 4;    /* TGSI_CC_ */
+   GLuint CondSwizzleX     : 2;    /* TGSI_SWIZZLE_ */
+   GLuint CondSwizzleY     : 2;    /* TGSI_SWIZZLE_ */
+   GLuint CondSwizzleZ     : 2;    /* TGSI_SWIZZLE_ */
+   GLuint CondSwizzleW     : 2;    /* TGSI_SWIZZLE_ */
+   GLuint CondDstUpdate    : 1;    /* BOOL */
+   GLuint CondFlowEnable   : 1;    /* BOOL */
+   GLuint Padding          : 1;
+   GLuint Extended         : 1;    /* BOOL */
+};
+
+struct tgsi_instruction_ext_label
+{
+   GLuint Type     : 4;    /* TGSI_INSTRUCTION_EXT_TYPE_LABEL */
+   GLuint Label    : 24;   /* UINT */
+   GLuint Target   : 1;    /* BOOL */
+   GLuint Padding  : 2;
+   GLuint Extended : 1;    /* BOOL */
+};
+
+#define TGSI_TEXTURE_UNKNOWN        0
+#define TGSI_TEXTURE_1D             1
+#define TGSI_TEXTURE_2D             2
+#define TGSI_TEXTURE_3D             3
+#define TGSI_TEXTURE_CUBE           4
+#define TGSI_TEXTURE_RECT           5
+#define TGSI_TEXTURE_SHADOW1D       6
+#define TGSI_TEXTURE_SHADOW2D       7
+#define TGSI_TEXTURE_SHADOWRECT     8
+
+struct tgsi_instruction_ext_texture
+{
+   GLuint Type     : 4;    /* TGSI_INSTRUCTION_EXT_TYPE_TEXTURE */
+   GLuint Texture  : 8;    /* TGSI_TEXTURE_ */
+   GLuint Padding  : 19;
+   GLuint Extended : 1;    /* BOOL */
+};
+
+/*
+ * File specifies the register array to access.
+ *
+ * Index specifies the element number of a register in the register file.
+ *
+ * If Indirect is TRUE, Index should be offset by the X component of a source
+ * register that follows. The register can be now fetched into local storage
+ * for further processing.
+ *
+ * If Negate is TRUE, all components of the fetched register are negated.
+ *
+ * The fetched register components are swizzled according to SwizzleX, SwizzleY,
+ * SwizzleZ and SwizzleW.
+ *
+ * If Extended is TRUE, any further modifications to the source register are
+ * made to this temporary storage.
+ */
+
+struct tgsi_src_register
+{
+   GLuint File         : 4;    /* TGSI_FILE_ */
+   GLuint SwizzleX     : 2;    /* TGSI_SWIZZLE_ */
+   GLuint SwizzleY     : 2;    /* TGSI_SWIZZLE_ */
+   GLuint SwizzleZ     : 2;    /* TGSI_SWIZZLE_ */
+   GLuint SwizzleW     : 2;    /* TGSI_SWIZZLE_ */
+   GLuint Negate       : 1;    /* BOOL */
+   GLuint Indirect     : 1;    /* BOOL */
+   GLuint Dimension    : 1;    /* BOOL */
+   GLint  Index        : 16;   /* SINT */
+   GLuint Extended     : 1;    /* BOOL */
+};
+
+/*
+ * If tgsi_src_register::Extended is TRUE, tgsi_src_register_ext follows.
+ * 
+ * Then, if tgsi_src_register::Indirect is TRUE, another tgsi_src_register
+ * follows.
+ *
+ * Then, if tgsi_src_register::Dimension is TRUE, tgsi_dimension follows.
+ */
+
+#define TGSI_SRC_REGISTER_EXT_TYPE_SWZ      0
+#define TGSI_SRC_REGISTER_EXT_TYPE_MOD      1
+
+struct tgsi_src_register_ext
+{
+   GLuint Type     : 4;    /* TGSI_SRC_REGISTER_EXT_TYPE_ */
+   GLuint Padding  : 27;
+   GLuint Extended : 1;    /* BOOL */
+};
+
+/*
+ * If tgsi_src_register_ext::Type is TGSI_SRC_REGISTER_EXT_TYPE_SWZ,
+ * it should be cast to tgsi_src_register_ext_extswz.
+ * 
+ * If tgsi_src_register_ext::Type is TGSI_SRC_REGISTER_EXT_TYPE_MOD,
+ * it should be cast to tgsi_src_register_ext_mod.
+ * 
+ * If tgsi_dst_register_ext::Extended is TRUE, another tgsi_dst_register_ext
+ * follows.
+ */
+
+#define TGSI_EXTSWIZZLE_X       TGSI_SWIZZLE_X
+#define TGSI_EXTSWIZZLE_Y       TGSI_SWIZZLE_Y
+#define TGSI_EXTSWIZZLE_Z       TGSI_SWIZZLE_Z
+#define TGSI_EXTSWIZZLE_W       TGSI_SWIZZLE_W
+#define TGSI_EXTSWIZZLE_ZERO    4
+#define TGSI_EXTSWIZZLE_ONE     5
+
+/*
+ * ExtSwizzleX, ExtSwizzleY, ExtSwizzleZ and ExtSwizzleW swizzle the source
+ * register in an extended manner.
+ *
+ * NegateX, NegateY, NegateZ and NegateW negate individual components of the
+ * source register.
+ *
+ * ExtDivide specifies which component is used to divide all components of the
+ * source register.
+ */
+
+struct tgsi_src_register_ext_swz
+{
+   GLuint Type         : 4;    /* TGSI_SRC_REGISTER_EXT_TYPE_SWZ */
+   GLuint ExtSwizzleX  : 4;    /* TGSI_EXTSWIZZLE_ */
+   GLuint ExtSwizzleY  : 4;    /* TGSI_EXTSWIZZLE_ */
+   GLuint ExtSwizzleZ  : 4;    /* TGSI_EXTSWIZZLE_ */
+   GLuint ExtSwizzleW  : 4;    /* TGSI_EXTSWIZZLE_ */
+   GLuint NegateX      : 1;    /* BOOL */
+   GLuint NegateY      : 1;    /* BOOL */
+   GLuint NegateZ      : 1;    /* BOOL */
+   GLuint NegateW      : 1;    /* BOOL */
+   GLuint ExtDivide    : 4;    /* TGSI_EXTSWIZZLE_ */
+   GLuint Padding      : 3;
+   GLuint Extended     : 1;    /* BOOL */
+};
+
+/*
+ * If Complement is TRUE, the source register is modified by subtracting it
+ * from 1.0.
+ *
+ * If Bias is TRUE, the source register is modified by subtracting 0.5 from it.
+ *
+ * If Scale2X is TRUE, the source register is modified by multiplying it by 2.0.
+ *
+ * If Absolute is TRUE, the source register is modified by removing the sign.
+ *
+ * If Negate is TRUE, the source register is modified by negating it.
+ */
+
+struct tgsi_src_register_ext_mod
+{
+   GLuint Type         : 4;    /* TGSI_SRC_REGISTER_EXT_TYPE_MOD */
+   GLuint Complement   : 1;    /* BOOL */
+   GLuint Bias         : 1;    /* BOOL */
+   GLuint Scale2X      : 1;    /* BOOL */
+   GLuint Absolute     : 1;    /* BOOL */
+   GLuint Negate       : 1;    /* BOOL */
+   GLuint Padding      : 22;
+   GLuint Extended     : 1;    /* BOOL */
+};
+
+struct tgsi_dimension
+{
+   GLuint Indirect     : 1;    /* BOOL */
+   GLuint Dimension    : 1;    /* BOOL */
+   GLuint Padding      : 13;
+   GLint  Index        : 16;   /* SINT */
+   GLuint Extended     : 1;    /* BOOL */
+};
+
+#define TGSI_WRITEMASK_NONE     0x00
+#define TGSI_WRITEMASK_X        0x01
+#define TGSI_WRITEMASK_Y        0x02
+#define TGSI_WRITEMASK_XY       0x03
+#define TGSI_WRITEMASK_Z        0x04
+#define TGSI_WRITEMASK_XZ       0x05
+#define TGSI_WRITEMASK_YZ       0x06
+#define TGSI_WRITEMASK_XYZ      0x07
+#define TGSI_WRITEMASK_W        0x08
+#define TGSI_WRITEMASK_XW       0x09
+#define TGSI_WRITEMASK_YW       0x0A
+#define TGSI_WRITEMASK_XYW      0x0B
+#define TGSI_WRITEMASK_ZW       0x0C
+#define TGSI_WRITEMASK_XZW      0x0D
+#define TGSI_WRITEMASK_YZW      0x0E
+#define TGSI_WRITEMASK_XYZW     0x0F
+
+struct tgsi_dst_register
+{
+   GLuint File         : 4;    /* TGSI_FILE_ */
+   GLuint WriteMask    : 4;    /* TGSI_WRITEMASK_ */
+   GLuint Indirect     : 1;    /* BOOL */
+   GLuint Dimension    : 1;    /* BOOL */
+   GLint  Index        : 16;   /* SINT */
+   GLuint Padding      : 5;
+   GLuint Extended     : 1;    /* BOOL */
+};
+
+/*
+ * If tgsi_dst_register::Extended is TRUE, tgsi_dst_register_ext follows.
+ * 
+ * Then, if tgsi_dst_register::Indirect is TRUE, tgsi_src_register follows.
+ */
+
+#define TGSI_DST_REGISTER_EXT_TYPE_CONDCODE     0
+#define TGSI_DST_REGISTER_EXT_TYPE_MODULATE     1
+
+struct tgsi_dst_register_ext
+{
+   GLuint Type     : 4;    /* TGSI_DST_REGISTER_EXT_TYPE_ */
+   GLuint Padding  : 27;
+   GLuint Extended : 1;    /* BOOL */
+};
+
+/*
+ * If tgsi_dst_register_ext::Type is TGSI_DST_REGISTER_EXT_TYPE_CONDCODE,
+ * it should be cast to tgsi_dst_register_ext_condcode.
+ * 
+ * If tgsi_dst_register_ext::Type is TGSI_DST_REGISTER_EXT_TYPE_MODULATE,
+ * it should be cast to tgsi_dst_register_ext_modulate.
+ * 
+ * If tgsi_dst_register_ext::Extended is TRUE, another tgsi_dst_register_ext
+ * follows.
+ */
+
+struct tgsi_dst_register_ext_concode
+{
+   GLuint Type         : 4;    /* TGSI_DST_REGISTER_EXT_TYPE_CONDCODE */
+   GLuint CondMask     : 4;    /* TGSI_CC_ */
+   GLuint CondSwizzleX : 2;    /* TGSI_SWIZZLE_ */
+   GLuint CondSwizzleY : 2;    /* TGSI_SWIZZLE_ */
+   GLuint CondSwizzleZ : 2;    /* TGSI_SWIZZLE_ */
+   GLuint CondSwizzleW : 2;    /* TGSI_SWIZZLE_ */
+   GLuint CondSrcIndex : 4;    /* UINT */
+   GLuint Padding      : 11;
+   GLuint Extended     : 1;    /* BOOL */
+};
+
+#define TGSI_MODULATE_1X        0
+#define TGSI_MODULATE_2X        1
+#define TGSI_MODULATE_4X        2
+#define TGSI_MODULATE_8X        3
+#define TGSI_MODULATE_HALF      4
+#define TGSI_MODULATE_QUARTER   5
+#define TGSI_MODULATE_EIGHTH    6
+
+struct tgsi_dst_register_ext_modulate
+{
+   GLuint Type     : 4;    /* TGSI_DST_REGISTER_EXT_TYPE_MODULATE */
+   GLuint Modulate : 4;    /* TGSI_MODULATE_ */
+   GLuint Padding  : 23;
+   GLuint Extended : 1;    /* BOOL */
+};
+
+#if defined __cplusplus
+} // extern "C"
+#endif // defined __cplusplus
+
+#endif // !defined TGSI_TOKEN_H
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_util.c b/src/mesa/pipe/tgsi/core/tgsi_util.c
new file mode 100644 (file)
index 0000000..38d6d6e
--- /dev/null
@@ -0,0 +1,270 @@
+#include "tgsi_platform.h"
+#include "tgsi_core.h"
+
+union pointer_hack
+{
+   void *pointer;
+   unsigned long long uint64;
+};
+
+void *
+tgsi_align_128bit(
+   void *unaligned )
+{
+   union pointer_hack ph;
+
+   ph.uint64 = 0;
+   ph.pointer = unaligned;
+   ph.uint64 = (ph.uint64 + 15) & ~15;
+   return ph.pointer;
+}
+
+GLuint
+tgsi_util_get_src_register_swizzle(
+   const struct tgsi_src_register *reg,
+   GLuint component )
+{
+   switch( component ) {
+   case 0:
+      return reg->SwizzleX;
+   case 1:
+      return reg->SwizzleY;
+   case 2:
+      return reg->SwizzleZ;
+   case 3:
+      return reg->SwizzleW;
+   default:
+      assert( 0 );
+   }
+   return 0;
+}
+
+GLuint
+tgsi_util_get_src_register_extswizzle(
+   const struct   tgsi_src_register_ext_swz *reg,
+   GLuint component )
+{
+   switch( component ) {
+   case 0:
+      return reg->ExtSwizzleX;
+   case 1:
+      return reg->ExtSwizzleY;
+   case 2:
+      return reg->ExtSwizzleZ;
+   case 3:
+      return reg->ExtSwizzleW;
+   default:
+      assert( 0 );
+   }
+   return 0;
+}
+
+GLuint
+tgsi_util_get_full_src_register_extswizzle(
+   const struct tgsi_full_src_register  *reg,
+   GLuint component )
+{
+   GLuint swizzle;
+
+   /*
+    * First, calculate  the   extended swizzle for a given channel. This will give
+    * us either a channel index into the simple swizzle or  a constant 1 or   0.
+    */
+   swizzle = tgsi_util_get_src_register_extswizzle(
+      &reg->SrcRegisterExtSwz,
+      component );
+
+   assert (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X);
+   assert (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y);
+   assert (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z);
+   assert (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W);
+   assert (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W);
+   assert (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W);
+
+   /*
+    * Second, calculate the simple  swizzle  for   the   unswizzled channel index.
+    * Leave the constants intact, they are   not   affected by the   simple swizzle.
+    */
+   if( swizzle <= TGSI_SWIZZLE_W ) {
+      swizzle = tgsi_util_get_src_register_swizzle(
+         &reg->SrcRegister,
+         swizzle );
+   }
+
+   return swizzle;
+}
+
+void
+tgsi_util_set_src_register_swizzle(
+   struct tgsi_src_register *reg,
+   GLuint swizzle,
+   GLuint component )
+{
+   switch( component ) {
+   case 0:
+      reg->SwizzleX = swizzle;
+      break;
+   case 1:
+      reg->SwizzleY = swizzle;
+      break;
+   case 2:
+      reg->SwizzleZ = swizzle;
+      break;
+   case 3:
+      reg->SwizzleW = swizzle;
+      break;
+   default:
+      assert( 0 );
+   }
+}
+
+void
+tgsi_util_set_src_register_extswizzle(
+   struct tgsi_src_register_ext_swz *reg,
+   GLuint swizzle,
+   GLuint component )
+{
+   switch( component ) {
+   case 0:
+      reg->ExtSwizzleX = swizzle;
+      break;
+   case 1:
+      reg->ExtSwizzleY = swizzle;
+      break;
+   case 2:
+      reg->ExtSwizzleZ = swizzle;
+      break;
+   case 3:
+      reg->ExtSwizzleW = swizzle;
+      break;
+   default:
+      assert( 0 );
+   }
+}
+
+GLuint
+tgsi_util_get_src_register_extnegate(
+   const  struct tgsi_src_register_ext_swz *reg,
+   GLuint component )
+{
+   switch( component ) {
+   case 0:
+      return reg->NegateX;
+   case 1:
+      return reg->NegateY;
+   case 2:
+      return reg->NegateZ;
+   case 3:
+      return reg->NegateW;
+   default:
+      assert( 0 );
+   }
+   return 0;
+}
+
+void
+tgsi_util_set_src_register_extnegate(
+   struct tgsi_src_register_ext_swz *reg,
+   GLuint negate,
+   GLuint component )
+{
+   switch( component ) {
+   case 0:
+      reg->NegateX = negate;
+      break;
+   case 1:
+      reg->NegateY = negate;
+      break;
+   case 2:
+      reg->NegateZ = negate;
+      break;
+   case 3:
+      reg->NegateW = negate;
+      break;
+   default:
+      assert( 0 );
+   }
+}
+
+GLuint
+tgsi_util_get_full_src_register_sign_mode(
+   const struct  tgsi_full_src_register *reg,
+   GLuint component )
+{
+   GLuint sign_mode;
+
+   if( reg->SrcRegisterExtMod.Absolute ) {
+      /* Consider only the post-abs negation. */
+
+      if( reg->SrcRegisterExtMod.Negate ) {
+         sign_mode = TGSI_UTIL_SIGN_SET;
+      }
+      else {
+         sign_mode = TGSI_UTIL_SIGN_CLEAR;
+      }
+   }
+   else {
+      /* Accumulate the three negations. */
+
+      GLuint negate;
+
+      negate = reg->SrcRegister.Negate;
+      if( tgsi_util_get_src_register_extnegate( &reg->SrcRegisterExtSwz, component ) ) {
+         negate = !negate;
+      }
+      if( reg->SrcRegisterExtMod.Negate ) {
+         negate = !negate;
+      }
+
+      if( negate ) {
+         sign_mode = TGSI_UTIL_SIGN_TOGGLE;
+      }
+      else {
+         sign_mode = TGSI_UTIL_SIGN_KEEP;
+      }
+   }
+
+   return sign_mode;
+}
+
+void
+tgsi_util_set_full_src_register_sign_mode(
+   struct tgsi_full_src_register *reg,
+   GLuint sign_mode )
+{
+   reg->SrcRegisterExtSwz.NegateX = 0;
+   reg->SrcRegisterExtSwz.NegateY = 0;
+   reg->SrcRegisterExtSwz.NegateZ = 0;
+   reg->SrcRegisterExtSwz.NegateW = 0;
+
+   switch (sign_mode)
+   {
+   case TGSI_UTIL_SIGN_CLEAR:
+      reg->SrcRegister.Negate = 0;
+      reg->SrcRegisterExtMod.Absolute = 1;
+      reg->SrcRegisterExtMod.Negate = 0;
+      break;
+
+   case TGSI_UTIL_SIGN_SET:
+      reg->SrcRegister.Negate = 0;
+      reg->SrcRegisterExtMod.Absolute = 1;
+      reg->SrcRegisterExtMod.Negate = 1;
+      break;
+
+   case TGSI_UTIL_SIGN_TOGGLE:
+      reg->SrcRegister.Negate = 1;
+      reg->SrcRegisterExtMod.Absolute = 0;
+      reg->SrcRegisterExtMod.Negate = 0;
+      break;
+
+   case TGSI_UTIL_SIGN_KEEP:
+      reg->SrcRegister.Negate = 0;
+      reg->SrcRegisterExtMod.Absolute = 0;
+      reg->SrcRegisterExtMod.Negate = 0;
+      break;
+
+   default:
+      assert( 0 );
+   }
+}
+
diff --git a/src/mesa/pipe/tgsi/core/tgsi_util.h b/src/mesa/pipe/tgsi/core/tgsi_util.h
new file mode 100644 (file)
index 0000000..70c4869
--- /dev/null
@@ -0,0 +1,70 @@
+#if !defined TGSI_UTIL_H
+#define TGSI_UTIL_H
+
+#if defined __cplusplus
+extern "C" {
+#endif // defined __cplusplus
+
+void *
+tgsi_align_128bit(
+   void *unaligned );
+
+GLuint
+tgsi_util_get_src_register_swizzle(
+   const struct tgsi_src_register *reg,
+   GLuint component );
+
+GLuint
+tgsi_util_get_src_register_extswizzle(
+   const struct tgsi_src_register_ext_swz *reg,
+   GLuint component);
+
+GLuint
+tgsi_util_get_full_src_register_extswizzle(
+   const struct tgsi_full_src_register *reg,
+   GLuint component );
+
+void
+tgsi_util_set_src_register_swizzle(
+   struct tgsi_src_register *reg,
+   GLuint swizzle,
+   GLuint component );
+
+void
+tgsi_util_set_src_register_extswizzle(
+   struct tgsi_src_register_ext_swz *reg,
+   GLuint swizzle,
+   GLuint component );
+
+GLuint
+tgsi_util_get_src_register_extnegate(
+   const struct tgsi_src_register_ext_swz *reg,
+   GLuint component );
+
+void
+tgsi_util_set_src_register_extnegate(
+   struct tgsi_src_register_ext_swz *reg,
+   GLuint negate,
+   GLuint component );
+
+#define TGSI_UTIL_SIGN_CLEAR    0   /* Force positive */
+#define TGSI_UTIL_SIGN_SET      1   /* Force negative */
+#define TGSI_UTIL_SIGN_TOGGLE   2   /* Negate */
+#define TGSI_UTIL_SIGN_KEEP     3   /* No change */
+
+GLuint
+tgsi_util_get_full_src_register_sign_mode(
+   const struct tgsi_full_src_register *reg,
+   GLuint component );
+
+void
+tgsi_util_set_full_src_register_sign_mode(
+   struct tgsi_full_src_register *reg,
+   GLuint sign_mode );
+
+#if defined __cplusplus
+} // extern "C"
+#endif // defined __cplusplus
+
+#endif // !defined TGSI_UTIL_H
+
diff --git a/src/mesa/pipe/tgsi/mesa/Makefile b/src/mesa/pipe/tgsi/mesa/Makefile
new file mode 100644 (file)
index 0000000..eb8b14e
--- /dev/null
@@ -0,0 +1,3 @@
+default:
+       cd ../../.. ; make
+
diff --git a/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c
new file mode 100644 (file)
index 0000000..a9415ac
--- /dev/null
@@ -0,0 +1,546 @@
+#include "tgsi_platform.h"\r
+#include "tgsi_mesa.h"\r
+\r
+/*\r
+ * Map mesa register file to SBIR register file.\r
+ */\r
+static GLuint\r
+map_register_file(\r
+   enum register_file file )\r
+{\r
+   switch( file ) {\r
+   case PROGRAM_UNDEFINED:\r
+      return TGSI_FILE_NULL;\r
+   case PROGRAM_TEMPORARY:\r
+      return TGSI_FILE_TEMPORARY;\r
+   //case PROGRAM_LOCAL_PARAM:\r
+   //case PROGRAM_ENV_PARAM:\r
+   case PROGRAM_STATE_VAR:\r
+   case PROGRAM_NAMED_PARAM:\r
+   case PROGRAM_CONSTANT:\r
+   case PROGRAM_UNIFORM:\r
+      return TGSI_FILE_CONSTANT;\r
+   case PROGRAM_INPUT:\r
+      return TGSI_FILE_INPUT;\r
+   case PROGRAM_OUTPUT:\r
+      return TGSI_FILE_OUTPUT;\r
+   case PROGRAM_ADDRESS:\r
+      return TGSI_FILE_ADDRESS;\r
+   default:\r
+      assert( 0 );\r
+      return TGSI_FILE_NULL;\r
+   }\r
+}\r
+\r
+/**\r
+ * Map mesa register file index to SBIR index.\r
+ * Take special care when processing input and output indices.\r
+ * \param processor  either TGSI_PROCESSOR_FRAGMENT or  TGSI_PROCESSOR_VERTEX\r
+ * \param file  one of TGSI_FILE_x\r
+ * \param index  the mesa register file index\r
+ * \param usage_bitmask  ???\r
+ */\r
+static GLuint\r
+map_register_file_index(\r
+   GLuint processor,\r
+   GLuint file,\r
+   GLuint index,\r
+   GLbitfield usage_bitmask )\r
+{\r
+   GLuint mapped_index;\r
+   GLuint i;\r
+\r
+   switch( file ) {\r
+   case TGSI_FILE_INPUT:\r
+      /*\r
+       * The fragment/vertex program input indexes (FRAG/VERT_ATTRIB_x) get\r
+       * mapped to a packed sequence of integers.\r
+       * If a program uses one input attribute, the mapped index will be 1.\r
+       * If a program uses two input attribs, the mapped indexes will be 1,2.\r
+       * If a program uses 3 input attribs, the mapped indexes will be 1,2,3.\r
+       * etc.\r
+       */\r
+      assert( index < 32 );\r
+      assert( usage_bitmask & (1 << index) );\r
+      mapped_index = 0;\r
+      for( i = 0; i < index; i++ ) {\r
+         if( usage_bitmask & (1 << i) ) {\r
+            mapped_index++;\r
+         }\r
+      }\r
+      printf("Map input %d to %d\n", index, mapped_index);\r
+      break;\r
+\r
+   case TGSI_FILE_OUTPUT:\r
+      assert( usage_bitmask == 0x0 );\r
+      if( processor == TGSI_PROCESSOR_FRAGMENT ) {\r
+         /* depth result  -> index 0\r
+          * color results -> index 1, 2, ...\r
+          */\r
+        if( index == FRAG_RESULT_DEPR ) {\r
+            mapped_index = 0;\r
+         }\r
+         else {\r
+            assert( index == FRAG_RESULT_COLR );\r
+            mapped_index = index + 1;\r
+         }\r
+      }\r
+      else {\r
+         /* mapped_index = VERT_RESULT_x */\r
+         mapped_index = index;\r
+      }\r
+      break;\r
+\r
+   default:\r
+      mapped_index = index;\r
+   }\r
+\r
+   return mapped_index;\r
+}\r
+\r
+/*\r
+ * Map mesa texture target to SBIR texture target.\r
+ */\r
+static GLuint\r
+map_texture_target(\r
+   GLuint textarget )\r
+{\r
+   switch( textarget ) {\r
+   case TEXTURE_1D_INDEX:\r
+      return TGSI_TEXTURE_1D;\r
+   case TEXTURE_2D_INDEX:\r
+      return TGSI_TEXTURE_2D;\r
+   case TEXTURE_3D_INDEX:\r
+      return TGSI_TEXTURE_3D;\r
+   case TEXTURE_CUBE_INDEX:\r
+      return TGSI_TEXTURE_CUBE;\r
+   case TEXTURE_RECT_INDEX:\r
+      return TGSI_TEXTURE_RECT;\r
+   default:\r
+      assert( 0 );\r
+   }\r
+\r
+   return TGSI_TEXTURE_1D;\r
+}\r
+\r
+static GLuint\r
+convert_sat(\r
+   GLuint sat )\r
+{\r
+   switch( sat ) {\r
+   case SATURATE_OFF:\r
+      return TGSI_SAT_NONE;\r
+   case SATURATE_ZERO_ONE:\r
+      return TGSI_SAT_ZERO_ONE;\r
+   case SATURATE_PLUS_MINUS_ONE:\r
+      return TGSI_SAT_MINUS_PLUS_ONE;\r
+   default:\r
+      assert( 0 );\r
+      return TGSI_SAT_NONE;\r
+   }\r
+}\r
+\r
+static GLuint\r
+convert_writemask(\r
+   GLuint writemask )\r
+{\r
+   assert( WRITEMASK_X == TGSI_WRITEMASK_X );\r
+   assert( WRITEMASK_Y == TGSI_WRITEMASK_Y );\r
+   assert( WRITEMASK_Z == TGSI_WRITEMASK_Z );\r
+   assert( WRITEMASK_W == TGSI_WRITEMASK_W );\r
+   assert( (writemask & ~TGSI_WRITEMASK_XYZW) == 0 );\r
+\r
+   return writemask;\r
+}\r
+\r
+static GLboolean\r
+compile_instruction(\r
+   const struct prog_instruction *inst,\r
+   struct tgsi_full_instruction *fullinst,\r
+   GLuint inputs_read,\r
+   GLuint processor )\r
+{\r
+   GLuint i;\r
+   struct tgsi_full_dst_register *fulldst;\r
+   struct tgsi_full_src_register *fullsrc;\r
+\r
+   *fullinst = tgsi_default_full_instruction();\r
+\r
+   fullinst->Instruction.Saturate = convert_sat( inst->SaturateMode );\r
+   fullinst->Instruction.NumDstRegs = 1;\r
+   fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs( inst->Opcode );\r
+\r
+   fulldst = &fullinst->FullDstRegisters[0];\r
+   fulldst->DstRegister.File = map_register_file( inst->DstReg.File );\r
+   fulldst->DstRegister.Index = map_register_file_index(\r
+      processor,\r
+      fulldst->DstRegister.File,\r
+      inst->DstReg.Index,\r
+      0x0 );\r
+   fulldst->DstRegister.WriteMask = convert_writemask( inst->DstReg.WriteMask );\r
+\r
+   for( i = 0; i < fullinst->Instruction.NumSrcRegs; i++ ) {\r
+      GLuint j;\r
+\r
+      fullsrc = &fullinst->FullSrcRegisters[i];\r
+      fullsrc->SrcRegister.File = map_register_file( inst->SrcReg[i].File );\r
+      fullsrc->SrcRegister.Index = map_register_file_index(\r
+         processor,\r
+         fullsrc->SrcRegister.File,\r
+         inst->SrcReg[i].Index,\r
+         inputs_read );\r
+\r
+      for( j = 0; j < 4; j++ ) {\r
+         GLuint swz;\r
+\r
+         swz = GET_SWZ( inst->SrcReg[i].Swizzle, j );\r
+         if( swz > SWIZZLE_W ) {\r
+            tgsi_util_set_src_register_extswizzle(\r
+               &fullsrc->SrcRegisterExtSwz,\r
+               swz,\r
+               j );\r
+         }\r
+         else {\r
+            tgsi_util_set_src_register_swizzle(\r
+               &fullsrc->SrcRegister,\r
+               swz,\r
+               j );\r
+         }\r
+      }\r
+\r
+      if( inst->SrcReg[i].NegateBase == NEGATE_XYZW ) {\r
+         fullsrc->SrcRegister.Negate = 1;\r
+      }\r
+      else if( inst->SrcReg[i].NegateBase != NEGATE_NONE ) {\r
+         if( inst->SrcReg[i].NegateBase & NEGATE_X ) {\r
+            fullsrc->SrcRegisterExtSwz.NegateX = 1;\r
+         }\r
+         if( inst->SrcReg[i].NegateBase & NEGATE_Y ) {\r
+            fullsrc->SrcRegisterExtSwz.NegateY = 1;\r
+         }\r
+         if( inst->SrcReg[i].NegateBase & NEGATE_Z ) {\r
+            fullsrc->SrcRegisterExtSwz.NegateZ = 1;\r
+         }\r
+         if( inst->SrcReg[i].NegateBase & NEGATE_W ) {\r
+            fullsrc->SrcRegisterExtSwz.NegateW = 1;\r
+         }\r
+      }\r
+\r
+      if( inst->SrcReg[i].Abs ) {\r
+         fullsrc->SrcRegisterExtMod.Absolute = 1;\r
+      }\r
+\r
+      if( inst->SrcReg[i].NegateAbs ) {\r
+         fullsrc->SrcRegisterExtMod.Negate = 1;\r
+      }\r
+\r
+      if( inst->SrcReg[i].RelAddr ) {\r
+         fullsrc->SrcRegister.Indirect = 1;\r
+\r
+         fullsrc->SrcRegisterInd.File = TGSI_FILE_ADDRESS;\r
+         fullsrc->SrcRegisterInd.Index = 0;\r
+      }\r
+   }\r
+\r
+   switch( inst->Opcode ) {\r
+   case OPCODE_ARL:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_ARL;\r
+      break;\r
+   case OPCODE_ABS:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_ABS;\r
+      break;\r
+   case OPCODE_ADD:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_ADD;\r
+      break;\r
+   case OPCODE_CMP:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_CMP;\r
+      break;\r
+   case OPCODE_COS:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_COS;\r
+      break;\r
+   case OPCODE_DP3:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_DP3;\r
+      break;\r
+   case OPCODE_DDX:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_DDX;\r
+      break;\r
+   case OPCODE_DDY:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_DDY;\r
+      break;\r
+   case OPCODE_DP4:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_DP4;\r
+      break;\r
+   case OPCODE_DPH:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_DPH;\r
+      break;\r
+   case OPCODE_DST:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_DST;\r
+      break;\r
+   case OPCODE_EX2:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_EX2;\r
+      break;\r
+   case OPCODE_FLR:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_FLR;\r
+      break;\r
+   case OPCODE_FRC:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_FRC;\r
+      break;\r
+   case OPCODE_KIL:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_KIL;\r
+      break;\r
+   case OPCODE_LG2:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_LG2;\r
+      break;\r
+   case OPCODE_LIT:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_LIT;\r
+      break;\r
+   case OPCODE_LRP:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_LRP;\r
+      break;\r
+   case OPCODE_MAD:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_MAD;\r
+      break;\r
+   case OPCODE_MAX:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_MAX;\r
+      break;\r
+   case OPCODE_MIN:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_MIN;\r
+      break;\r
+   case OPCODE_MOV:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_MOV;\r
+      break;\r
+   case OPCODE_MUL:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_MUL;\r
+      break;\r
+   case OPCODE_POW:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_POW;\r
+      break;\r
+   case OPCODE_RCP:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_RCP;\r
+      break;\r
+   case OPCODE_RSQ:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ;\r
+      tgsi_util_set_full_src_register_sign_mode(\r
+         &fullinst->FullSrcRegisters[0],\r
+         TGSI_UTIL_SIGN_CLEAR );\r
+      break;\r
+   case OPCODE_SCS:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_SCS;\r
+      fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XY;\r
+      break;\r
+   case OPCODE_SGE:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_SGE;\r
+      break;\r
+   case OPCODE_SIN:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_SIN;\r
+      break;\r
+   case OPCODE_SLT:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_SLT;\r
+      break;\r
+   case OPCODE_SUB:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_SUB;\r
+      break;\r
+   case OPCODE_SWZ:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_SWZ;\r
+      break;\r
+   case OPCODE_TEX:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;\r
+      fullinst->Instruction.NumSrcRegs = 2;\r
+      fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
+      fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
+      fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
+      break;\r
+   case OPCODE_TXB:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_TXB;\r
+      fullinst->Instruction.NumSrcRegs = 2;\r
+      fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
+      fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
+      fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
+      break;\r
+   case OPCODE_TXP:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;\r
+      fullinst->Instruction.NumSrcRegs = 2;\r
+      fullinst->InstructionExtTexture.Texture = map_texture_target( inst->TexSrcTarget );\r
+      fullinst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide = TGSI_EXTSWIZZLE_W;\r
+      fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;\r
+      fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;\r
+      break;\r
+   case OPCODE_XPD:\r
+      fullinst->Instruction.Opcode = TGSI_OPCODE_XPD;\r
+      fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XYZ;\r
+      break;\r
+   case OPCODE_END:\r
+      return GL_TRUE;\r
+   default:\r
+      assert( 0 );\r
+   }\r
+\r
+   return GL_FALSE;\r
+}\r
+\r
+GLboolean\r
+tgsi_mesa_compile_fp_program(\r
+   const struct gl_fragment_program *program,\r
+   struct tgsi_token *tokens,\r
+   GLuint maxTokens )\r
+{\r
+   GLuint i, ti;\r
+   struct tgsi_header *header;\r
+   struct tgsi_full_declaration fulldecl;\r
+   struct tgsi_full_instruction fullinst;\r
+   struct tgsi_full_dst_register *fulldst;\r
+   struct tgsi_full_src_register *fullsrc;\r
+   GLuint inputs_read;\r
+\r
+   *(struct tgsi_version *) &tokens[0] = tgsi_build_version();\r
+\r
+   header = (struct tgsi_header *) &tokens[1];\r
+   *header = tgsi_build_header();\r
+\r
+   ti = 2;\r
+\r
+   /*\r
+    * Input 0 is always read, at least implicitly by the instruction generated\r
+    * above, so mark it as used.\r
+    */\r
+   inputs_read = program->Base.InputsRead | 1;\r
+\r
+   /*\r
+    * Declare input attributes.\r
+    */\r
+   fulldecl = tgsi_default_full_declaration();\r
+\r
+   fulldecl.Declaration.File = TGSI_FILE_INPUT;\r
+   fulldecl.Declaration.Declare = TGSI_DECLARE_RANGE;\r
+   fulldecl.Declaration.Interpolate = 1;\r
+\r
+   /*\r
+    * Do not interpolate fragment position.\r
+    */\r
+   fulldecl.u.DeclarationRange.First = 0;\r
+   fulldecl.u.DeclarationRange.Last = 0;\r
+\r
+   fulldecl.Interpolation.Interpolate = TGSI_INTERPOLATE_CONSTANT;\r
+\r
+   ti += tgsi_build_full_declaration(\r
+      &fulldecl,\r
+      &tokens[ti],\r
+      header,\r
+      maxTokens - ti );\r
+\r
+   /*\r
+    * Interpolate generic attributes.\r
+    */\r
+   fulldecl.u.DeclarationRange.First = 1;\r
+   fulldecl.u.DeclarationRange.Last = 1;\r
+   for( i = 1; i < 32; i++ ) {\r
+      if( inputs_read & (1 << i) ) {\r
+         fulldecl.u.DeclarationRange.Last++;\r
+      }\r
+   }\r
+\r
+   fulldecl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR;\r
+\r
+   ti += tgsi_build_full_declaration(\r
+      &fulldecl,\r
+      &tokens[ti],\r
+      header,\r
+      maxTokens - ti );\r
+\r
+   /*\r
+    * Copy input fragment xyz to output xyz.\r
+    * If the shader writes depth, do not copy the z component.\r
+    */\r
+\r
+   fullinst = tgsi_default_full_instruction();\r
+\r
+   fullinst.Instruction.Opcode = TGSI_OPCODE_MOV;\r
+   fullinst.Instruction.NumDstRegs = 1;\r
+   fullinst.Instruction.NumSrcRegs = 1;\r
+\r
+   fulldst = &fullinst.FullDstRegisters[0];\r
+   fulldst->DstRegister.File = TGSI_FILE_OUTPUT;\r
+   fulldst->DstRegister.Index = 0;\r
+   if( program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR) ) {\r
+      fulldst->DstRegister.WriteMask = TGSI_WRITEMASK_XY;\r
+   }\r
+   else {\r
+      fulldst->DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;\r
+   }\r
+\r
+   fullsrc = &fullinst.FullSrcRegisters[0];\r
+   fullsrc->SrcRegister.File = TGSI_FILE_INPUT;\r
+   fullsrc->SrcRegister.Index = 0;\r
+\r
+   ti += tgsi_build_full_instruction(\r
+      &fullinst,\r
+      &tokens[ti],\r
+      header,\r
+      maxTokens - ti );\r
+\r
+   for( i = 0; i < program->Base.NumInstructions; i++ ) {\r
+      if( compile_instruction(\r
+            &program->Base.Instructions[i],\r
+            &fullinst,\r
+            inputs_read,\r
+            TGSI_PROCESSOR_FRAGMENT ) ) {\r
+         assert( i == program->Base.NumInstructions - 1 );\r
+         tgsi_dump(\r
+            tokens,\r
+            TGSI_DUMP_NO_IGNORED | TGSI_DUMP_NO_DEFAULT );\r
+         break;\r
+      }\r
+\r
+      ti += tgsi_build_full_instruction(\r
+         &fullinst,\r
+         &tokens[ti],\r
+         header,\r
+         maxTokens - ti );\r
+   }\r
+\r
+   return GL_TRUE;\r
+}\r
+\r
+GLboolean\r
+tgsi_mesa_compile_vp_program(\r
+   const struct gl_vertex_program *program,\r
+   struct tgsi_token *tokens,\r
+   GLuint maxTokens )\r
+{\r
+   GLuint ii, ti;\r
+   struct tgsi_header *header;\r
+   struct tgsi_processor *processor;\r
+   struct tgsi_full_instruction fullinst;\r
+   GLuint inputs_read = ~0;\r
+\r
+   *(struct tgsi_version *) &tokens[0] = tgsi_build_version();\r
+\r
+   header = (struct tgsi_header *) &tokens[1];\r
+   *header = tgsi_build_header();\r
+\r
+   processor = (struct tgsi_processor *) &tokens[2];\r
+   *processor = tgsi_build_processor( TGSI_PROCESSOR_VERTEX, header );\r
+\r
+   ti = 3;\r
+\r
+   for( ii = 0; ii < program->Base.NumInstructions; ii++ ) {\r
+      if( compile_instruction(\r
+            &program->Base.Instructions[ii],\r
+            &fullinst,\r
+            inputs_read,\r
+            TGSI_PROCESSOR_VERTEX ) ) {\r
+         assert( ii == program->Base.NumInstructions - 1 );\r
+         tgsi_dump( tokens, TGSI_DUMP_NO_IGNORED | TGSI_DUMP_NO_DEFAULT );\r
+         break;\r
+      }\r
+\r
+      ti += tgsi_build_full_instruction(\r
+         &fullinst,\r
+         &tokens[ti],\r
+         header,\r
+         maxTokens - ti );\r
+   }\r
+\r
+   return GL_TRUE;\r
+}\r
+\r
diff --git a/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.h b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.h
new file mode 100644 (file)
index 0000000..9256318
--- /dev/null
@@ -0,0 +1,27 @@
+#if !defined MESA_TO_TGSI_H\r
+#define MESA_TO_TGSI_H\r
+\r
+#if defined __cplusplus\r
+extern "C" {\r
+#endif // defined __cplusplus\r
+\r
+struct tgsi_token;\r
+\r
+GLboolean\r
+tgsi_mesa_compile_fp_program(\r
+   const struct gl_fragment_program *program,\r
+   struct tgsi_token *tokens,\r
+   GLuint maxTokens );\r
+\r
+GLboolean\r
+tgsi_mesa_compile_vp_program(\r
+   const struct gl_vertex_program *program,\r
+   struct tgsi_token *tokens,\r
+   GLuint maxTokens );\r
+\r
+#if defined __cplusplus\r
+} // extern "C"\r
+#endif // defined __cplusplus\r
+\r
+#endif // !defined MESA_TO_TGSI_H\r
+\r
diff --git a/src/mesa/pipe/tgsi/mesa/tgsi_mesa.h b/src/mesa/pipe/tgsi/mesa/tgsi_mesa.h
new file mode 100644 (file)
index 0000000..0053748
--- /dev/null
@@ -0,0 +1,8 @@
+#if !defined TGSI_MESA_H\r
+#define TGSI_MESA_H\r
+\r
+#include "../core/tgsi_core.h"\r
+#include "mesa_to_tgsi.h"\r
+\r
+#endif // !defined TGSI_MESA_H\r
+\r
diff --git a/src/mesa/pipe/tgsi/tgsi_platform.h b/src/mesa/pipe/tgsi/tgsi_platform.h
new file mode 100644 (file)
index 0000000..553f0b2
--- /dev/null
@@ -0,0 +1,18 @@
+#if !defined TGSI_PLATFORM_H
+#define TGSI_PLATFORM_H
+
+#if defined __cplusplus
+extern "C" {
+#endif // defined __cplusplus
+
+#include "imports.h"
+#include "mtypes.h"
+#include "prog_instruction.h"
+#include "program.h"
+
+#if defined __cplusplus
+} // extern "C"
+#endif // defined __cplusplus
+
+#endif // !defined TGSI_PLATFORM_H
+
index 5d8f763741fabcb6dc00e47d9684bcfaa3eaae89..9a5290d920e35685f16bbac4333d3f92c375af89 100644 (file)
  * \author Karl Rasche
  */
 
-#include "glheader.h"
-#include "imports.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "shader/grammar/grammar_mesa.h"
 #include "arbprogparse.h"
-#include "grammar_mesa.h"
 #include "program.h"
 #include "prog_parameter.h"
 #include "prog_statevars.h"
@@ -3573,7 +3573,7 @@ parse_instructions(GLcontext * ctx, const GLubyte * inst,
 
 /* XXX temporary */
 LONGSTRING static char core_grammar_text[] =
-#include "grammar_syn.h"
+#include "shader/grammar/grammar_syn.h"
 ;
 
 
index 9faf9d86134e91d47c5fd409285710f3173c0d6e..28d195d0ee95393db885dc8c4a0f73eeea7879fd 100644 (file)
@@ -43,7 +43,7 @@
 #include "prog_instruction.h"
 #include "prog_parameter.h"
 #include "prog_print.h"
-#include "slang_library_noise.h"
+#include "shader/slang/slang_library_noise.h"
 
 
 /* See comments below for info about this */
index 420591982825d95fc8401f784032b44a726da747..1f227390afd3551dcb67eb3a56c34d895c59b7a7 100644 (file)
@@ -333,7 +333,7 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
 {
    struct gl_program *clone;
 
-   clone = _mesa_new_program(ctx, prog->Target, prog->Id);
+   clone = ctx->Driver.NewProgram(ctx, prog->Target, prog->Id);
    if (!clone)
       return NULL;
 
index 3a54e68d0de8374fb31a2aca2dd6efc0b21fcfe0..1a931326afa3a9d5117429fb32c85ebce5368bdd 100644 (file)
 #include "prog_parameter.h"
 #include "prog_print.h"
 #include "prog_statevars.h"
-#include "shader_api.h"
-
-#include "slang_compile.h"
-#include "slang_link.h"
+#include "shader/shader_api.h"
+#include "shader/slang/slang_compile.h"
+#include "shader/slang/slang_link.h"
 
 
 
@@ -780,7 +779,7 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program,
       *params = shProg->Validated;
       break;
    case GL_INFO_LOG_LENGTH:
-      *params = shProg->InfoLog ? strlen(shProg->InfoLog) : 0;
+      *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
       break;
    case GL_ATTACHED_SHADERS:
       *params = shProg->NumShaders;
@@ -832,10 +831,10 @@ _mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
       *params = shader->CompileStatus;
       break;
    case GL_INFO_LOG_LENGTH:
-      *params = shader->InfoLog ? strlen(shader->InfoLog) : 0;
+      *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
       break;
    case GL_SHADER_SOURCE_LENGTH:
-      *params = shader->Source ? strlen((char *) shader->Source) : 0;
+      *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
       break;
    default:
       _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
index 6ee0fd33b6a1f977fd4589a7d801091ec1cf69af..1081d8ff8db744d06fc58069f4d2e262ad76b7e4 100644 (file)
  * \author Brian Paul
  */
 
-#include "imports.h"
-#include "slang_builtin.h"
-#include "slang_ir.h"
-#include "mtypes.h"
-#include "program.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_statevars.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "shader/program.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_statevars.h"
+#include "shader/slang/slang_ir.h"
+#include "shader/slang/slang_builtin.h"
 
 
 /**
index ae20c844d5872002e1989f4abc3152b6923d97d9..58629f4f7fe3a1a7ccdc2612809f32c4cf484a98 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef SLANG_BUILTIN_H
 #define SLANG_BUILTIN_H
 
-#include "prog_parameter.h"
+#include "shader/prog_parameter.h"
 #include "slang_utility.h"
 #include "slang_ir.h"
 
index f3a6d04428f6c4539e353e412ec6752452cc83be..8b2bdd74b596ee5df0a5e771a79d1424bb116621 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.1
  *
  * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
  *
 
 
 
-#include "imports.h"
-#include "macros.h"
-#include "mtypes.h"
-#include "program.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_statevars.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "shader/program.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_statevars.h"
 #include "slang_typeinfo.h"
 #include "slang_codegen.h"
 #include "slang_compile.h"
@@ -536,7 +536,7 @@ new_not(slang_ir_node *n)
 static slang_ir_node *
 new_inlined_function_call(slang_ir_node *code, slang_label *name)
 {
-   slang_ir_node *n = new_node1(IR_FUNC, code);
+   slang_ir_node *n = new_node1(IR_CALL, code);
    assert(name);
    if (n)
       n->Label = name;
@@ -1202,17 +1202,29 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun,
       /* non-assembly function */
       inlined = slang_inline_function_call(A, fun, oper, dest);
       if (inlined && _slang_find_node_type(inlined, SLANG_OPER_RETURN)) {
-         /* This inlined function has one or more 'return' statements.
+         slang_operation *callOper;
+         /* The function we're calling has one or more 'return' statements.
           * So, we can't truly inline this function because we need to
           * implement 'return' with RET (and CAL).
+          * Nevertheless, we performed "inlining" to make a new instance
+          * of the function body to deal with static register allocation.
+          *
           * XXX check if there's one 'return' and if it's the very last
           * statement in the function - we can optimize that case.
           */
          assert(inlined->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
                 inlined->type == SLANG_OPER_SEQUENCE);
-         inlined->type = SLANG_OPER_INLINED_CALL;
-         inlined->fun = fun;
-         inlined->label = _slang_label_new_unique((char*) fun->header.a_name);
+         if (_slang_function_has_return_value(fun) && !dest) {
+            assert(inlined->children[0].type == SLANG_OPER_VARIABLE_DECL);
+            assert(inlined->children[2].type == SLANG_OPER_IDENTIFIER);
+            callOper = &inlined->children[1];
+         }
+         else {
+            callOper = inlined;
+         }
+         callOper->type = SLANG_OPER_INLINED_CALL;
+         callOper->fun = fun;
+         callOper->label = _slang_label_new_unique((char*) fun->header.a_name);
       }
    }
 
@@ -1949,8 +1961,7 @@ static slang_ir_node *
 _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
 {
    const GLboolean haveReturnValue
-      = (oper->num_children == 1 &&
-         oper->children[0].type != SLANG_OPER_VOID);
+      = (oper->num_children == 1 && oper->children[0].type != SLANG_OPER_VOID);
 
    /* error checking */
    assert(A->CurFunction);
@@ -1960,7 +1971,7 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
       return NULL;
    }
    else if (!haveReturnValue &&
-       A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
+            A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
       slang_info_log_error(A->log, "return statement requires an expression");
       return NULL;
    }
@@ -2236,7 +2247,9 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper)
       }
       if (var->type.qualifier == SLANG_QUAL_CONST ||
           var->type.qualifier == SLANG_QUAL_ATTRIBUTE ||
-          var->type.qualifier == SLANG_QUAL_UNIFORM) {
+          var->type.qualifier == SLANG_QUAL_UNIFORM ||
+          (var->type.qualifier == SLANG_QUAL_VARYING &&
+           A->program->Target == GL_FRAGMENT_PROGRAM_ARB)) {
          slang_info_log_error(A->log,
                               "illegal assignment to read-only variable '%s'",
                               (char *) oper->children[0].a_id);
@@ -2264,10 +2277,11 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper)
       lhs = _slang_gen_operation(A, &oper->children[0]);
 
       if (lhs) {
-         if (lhs->Store->File != PROGRAM_OUTPUT &&
-             lhs->Store->File != PROGRAM_TEMPORARY &&
-             lhs->Store->File != PROGRAM_VARYING &&
-             lhs->Store->File != PROGRAM_UNDEFINED) {
+         if (!(lhs->Store->File == PROGRAM_OUTPUT ||
+               lhs->Store->File == PROGRAM_TEMPORARY ||
+               (lhs->Store->File == PROGRAM_VARYING &&
+                A->program->Target == GL_VERTEX_PROGRAM_ARB) ||
+               lhs->Store->File == PROGRAM_UNDEFINED)) {
             slang_info_log_error(A->log,
                                  "illegal assignment to read-only l-value");
             return NULL;
@@ -2328,7 +2342,8 @@ _slang_gen_field(slang_assemble_ctx * A, slang_operation *oper)
          n = _slang_gen_swizzle(n, swizzle);
       return n;
    }
-   else if (ti.spec.type == SLANG_SPEC_FLOAT) {
+   else if (   ti.spec.type == SLANG_SPEC_FLOAT
+            || ti.spec.type == SLANG_SPEC_INT) {
       const GLuint rows = 1;
       slang_swizzle swz;
       slang_ir_node *n;
index a4dd5b8b4ae237d8400a2d85b530cd6f1308213f..4e29e8dcc90adcbb406dbec9a2c4d40b4ea09a4a 100644 (file)
  * \author Michal Krol
  */
 
-#include "imports.h"
-#include "context.h"
-#include "program.h"
-#include "prog_parameter.h"
-#include "grammar_mesa.h"
+#include "main/imports.h"
+#include "main/context.h"
+#include "shader/program.h"
+#include "shader/prog_parameter.h"
+#include "shader/grammar/grammar_mesa.h"
 #include "slang_codegen.h"
 #include "slang_compile.h"
 #include "slang_preprocess.h"
@@ -2135,7 +2135,7 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
          progTarget = GL_FRAGMENT_PROGRAM_ARB;
       shader->Programs
          = (struct gl_program **) malloc(sizeof(struct gl_program*));
-      shader->Programs[0] = _mesa_new_program(ctx, progTarget, 1);
+      shader->Programs[0] = ctx->Driver.NewProgram(ctx, progTarget, 1);
       shader->NumPrograms = 1;
 
       shader->Programs[0]->Parameters = _mesa_new_parameter_list();
index 7804e192360a9d47514f217bc2716bad74216c48..fe13f2865cda606a15c73bb3ad09dead454ad8be 100644 (file)
  ***/
 
 
-#include "imports.h"
-#include "context.h"
-#include "macros.h"
-#include "program.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
+#include "main/imports.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "shader/program.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
 #include "slang_builtin.h"
 #include "slang_emit.h"
 #include "slang_mem.h"
@@ -780,16 +780,18 @@ emit_label(slang_emit_info *emitInfo, const slang_ir_node *n)
 
 
 /**
- * Emit code for an inlined function call (subroutine).
+ * Emit code for a function call.
+ * Note that for each time a function is called, we emit the function's
+ * body code again because the set of available registers may be different.
  */
 static struct prog_instruction *
-emit_func(slang_emit_info *emitInfo, slang_ir_node *n)
+emit_fcall(slang_emit_info *emitInfo, slang_ir_node *n)
 {
    struct gl_program *progSave;
    struct prog_instruction *inst;
    GLuint subroutineId;
 
-   assert(n->Opcode == IR_FUNC);
+   assert(n->Opcode == IR_CALL);
    assert(n->Label);
 
    /* save/push cur program */
@@ -1687,10 +1689,10 @@ emit(slang_emit_info *emitInfo, slang_ir_node *n)
    case IR_KILL:
       return emit_kill(emitInfo);
 
-   case IR_FUNC:
-      /* new variable scope for subroutines/function calls*/
+   case IR_CALL:
+      /* new variable scope for subroutines/function calls */
       _slang_push_var_table(emitInfo->vt);
-      inst = emit_func(emitInfo, n);
+      inst = emit_fcall(emitInfo, n);
       _slang_pop_var_table(emitInfo->vt);
       return inst;
 
@@ -1782,7 +1784,7 @@ _slang_resolve_subroutines(slang_emit_info *emitInfo)
    emitInfo->NumSubroutines = 0;
 
    /* Examine CAL instructions.
-    * At this point, the BranchTarget field of the CAL instructions is
+    * At this point, the BranchTarget field of the CAL instruction is
     * the number/id of the subroutine to call (an index into the
     * emitInfo->Subroutines list).
     * Translate that into an actual instruction location now.
index a6903cc8b625211be165411c97e677aed0e0a45b..92e8d0345eec0b76bd4c083f978541f19f5dea04 100644 (file)
@@ -27,7 +27,7 @@
 #include "context.h"
 #include "slang_ir.h"
 #include "slang_mem.h"
-#include "prog_print.h"
+#include "shader/prog_print.h"
 
 
 static const slang_ir_info IrInfo[] = {
@@ -311,7 +311,7 @@ _slang_print_ir_tree(const slang_ir_node *n, int indent)
       printf("RETURN\n");
       break;
    case IR_CALL:
-      printf("CALL\n");
+      printf("CALL %s\n", n->Label->Name);
       break;
 
    case IR_LOOP:
index 69db4b5451ec111cfcb643e2dfd90570a1548022..c7c0ddbf9a69cee75449373da6478e39381ddcbf 100644 (file)
@@ -62,8 +62,6 @@ typedef enum
    IR_RETURN,    /* return from subroutine */
    IR_CALL,      /* call subroutine */
 
-   IR_FUNC,      /* inlined function code */
-
    IR_LOOP,      /* high-level loop-begin / loop-end */
                  /* Children[0] = loop body */
                  /* Children[1] = loop tail code, or NULL */
index 0f1a45b30f9febeda921144855434507a94ea214..87068ae7a7fefb04dfe207f9353b65f003963e17 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef SLANG_LABEL_H
 #define SLANG_LABEL_H 1
 
-#include "imports.h"
-#include "mtypes.h"
-#include "prog_instruction.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "shader/prog_instruction.h"
 
 
 struct slang_label_
index d6d1c7523e5d94adffc8b6967fa32b8433c9f772..eaa29ba094e6463ac16042789c0e6e59348d9d36 100644 (file)
  * \author Brian Paul
  */
 
-#include "imports.h"
-#include "context.h"
-#include "hash.h"
-#include "macros.h"
-#include "program.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "prog_statevars.h"
-#include "shader_api.h"
+#include "main/imports.h"
+#include "main/context.h"
+#include "main/hash.h"
+#include "main/macros.h"
+#include "shader/program.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
+#include "shader/prog_statevars.h"
+#include "shader/shader_api.h"
 #include "slang_link.h"
 
 
index 72281eda57de9db59fd2aa9163898a95aabbbf4d..076e982f8f29d5bd6f70fdf9fe4337ff330249ff 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 #include "imports.h"
-#include "grammar_mesa.h"
+#include "shader/grammar/grammar_mesa.h"
 #include "slang_preprocess.h"
 
 LONGSTRING static const char *slang_pp_directives_syn =
index da0b32bc44467d3a5675f548fffc67aa9cdd0329..8a1c3abf4807df21510511cf62f0af37fa05e808 100644 (file)
  * \author Michal Krol
  */
 
-#include "imports.h"
+#include "main/imports.h"
+#include "shader/prog_instruction.h"
 #include "slang_typeinfo.h"
 #include "slang_compile.h"
 #include "slang_log.h"
 #include "slang_mem.h"
-#include "prog_instruction.h"
 
 
 /**
index 8a3c299d19cad48c6fe33975f785e45d82f21fe7..1d817000c60b0b3fcd0be52ef0e3976ec348b7d8 100644 (file)
@@ -1,11 +1,11 @@
 
-#include "imports.h"
+#include "main/imports.h"
+#include "shader/prog_instruction.h"
 #include "slang_compile.h"
 #include "slang_compile_variable.h"
 #include "slang_mem.h"
 #include "slang_vartable.h"
 #include "slang_ir.h"
-#include "prog_instruction.h"
 
 
 static int dbg = 0;
index dbfc01d0edfb2270ee27b4e930a2ad2d2b4ef90c..32c2ff23500101aeef377122251c930d1cfc5b76 100644 (file)
@@ -149,6 +149,76 @@ VBO_SOURCES = \
        vbo/vbo_save_draw.c \
        vbo/vbo_save_loopback.c 
 
+VF_SOURCES = \
+       vf/vf.c \
+       vf/vf_generic.c \
+       vf/vf_sse.c
+
+SOFTPIPE_SOURCES = \
+       pipe/softpipe/sp_clear.c \
+       pipe/softpipe/sp_context.c \
+       pipe/softpipe/sp_quad.c \
+       pipe/softpipe/sp_quad_alpha_test.c \
+       pipe/softpipe/sp_quad_blend.c \
+       pipe/softpipe/sp_quad_bufloop.c \
+       pipe/softpipe/sp_quad_colormask.c \
+       pipe/softpipe/sp_quad_coverage.c \
+       pipe/softpipe/sp_quad_depth_test.c \
+       pipe/softpipe/sp_quad_fs.c \
+       pipe/softpipe/sp_quad_occlusion.c \
+       pipe/softpipe/sp_quad_output.c \
+       pipe/softpipe/sp_quad_stipple.c \
+       pipe/softpipe/sp_quad_stencil.c \
+       pipe/softpipe/sp_state_blend.c \
+       pipe/softpipe/sp_state_clip.c \
+       pipe/softpipe/sp_state_derived.c \
+       pipe/softpipe/sp_state_fs.c \
+       pipe/softpipe/sp_state_sampler.c \
+       pipe/softpipe/sp_state_setup.c \
+       pipe/softpipe/sp_state_surface.c \
+       pipe/softpipe/sp_z_surface.c \
+       pipe/softpipe/sp_prim_setup.c
+
+DRAW_SOURCES = \
+       pipe/draw/draw_clip.c \
+       pipe/draw/draw_context.c\
+       pipe/draw/draw_cull.c \
+       pipe/draw/draw_flatshade.c \
+       pipe/draw/draw_offset.c \
+       pipe/draw/draw_twoside.c \
+       pipe/draw/draw_unfilled.c \
+       pipe/draw/draw_vb.c
+
+TGSICORE_SOURCES = \
+       pipe/tgsi/core/tgsi_build.c \
+       pipe/tgsi/core/tgsi_dump.c \
+       pipe/tgsi/core/tgsi_exec.c \
+       pipe/tgsi/core/tgsi_parse.c \
+       pipe/tgsi/core/tgsi_util.c
+
+TGSIMESA_SOURCES = \
+       pipe/tgsi/mesa/mesa_to_tgsi.c
+
+STATETRACKER_SOURCES = \
+       state_tracker/st_atom.c \
+       state_tracker/st_atom_alphatest.c \
+       state_tracker/st_atom_blend.c \
+       state_tracker/st_atom_clear_color.c \
+       state_tracker/st_atom_clip.c \
+       state_tracker/st_atom_depth.c \
+       state_tracker/st_atom_fs.c \
+       state_tracker/st_atom_vs.c \
+       state_tracker/st_atom_framebuffer.c \
+       state_tracker/st_atom_sampler.c \
+       state_tracker/st_atom_scissor.c \
+       state_tracker/st_atom_setup.c \
+       state_tracker/st_atom_stencil.c \
+       state_tracker/st_atom_stipple.c \
+       state_tracker/st_atom_viewport.c \
+       state_tracker/st_cb_program.c \
+       state_tracker/st_draw.c \
+       state_tracker/st_context.c \
+       state_tracker/st_texobj.c
 
 SHADER_SOURCES = \
        shader/arbprogparse.c \
@@ -250,6 +320,7 @@ X11_DRIVER_SOURCES =                \
        drivers/x11/xm_glide.c  \
        drivers/x11/xm_line.c   \
        drivers/x11/xm_span.c   \
+       drivers/x11/xm_surface.c        \
        drivers/x11/xm_tri.c
 
 OSMESA_DRIVER_SOURCES = \
@@ -294,6 +365,12 @@ SOLO_SOURCES = \
        $(MAIN_SOURCES)         \
        $(MATH_SOURCES)         \
        $(VBO_SOURCES)          \
+       $(VF_SOURCES)           \
+       $(SOFTPIPE_SOURCES)     \
+       $(DRAW_SOURCES)         \
+       $(TGSICORE_SOURCES)     \
+       $(TGSIMESA_SOURCES)     \
+       $(STATETRACKER_SOURCES) \
        $(TNL_SOURCES)          \
        $(SHADER_SOURCES)       \
        $(SWRAST_SOURCES)       \
@@ -339,4 +416,5 @@ INCLUDE_DIRS = \
        -I$(TOP)/src/mesa/shader/grammar \
        -I$(TOP)/src/mesa/shader/slang \
        -I$(TOP)/src/mesa/swrast \
-       -I$(TOP)/src/mesa/swrast_setup
+       -I$(TOP)/src/mesa/swrast_setup \
+       -I$(TOP)/src/mesa/pipe/tgsi
diff --git a/src/mesa/state_tracker/Makefile b/src/mesa/state_tracker/Makefile
new file mode 100644 (file)
index 0000000..0ab1dc6
--- /dev/null
@@ -0,0 +1,2 @@
+default:
+       cd ../.. ; make
\ No newline at end of file
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
new file mode 100644 (file)
index 0000000..85c99bc
--- /dev/null
@@ -0,0 +1,175 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+
+#include "glheader.h"
+#include "context.h"
+
+#include "st_context.h"
+#include "st_atom.h"
+
+       
+
+/* This is used to initialize st->atoms[].  We could use this list
+ * directly except for a single atom, st_update_constants, which has a
+ * .dirty value which changes according to the parameters of the
+ * current fragment and vertex programs, and so cannot be a static
+ * value.
+ */
+static const struct st_tracked_state *atoms[] =
+{
+   &st_update_framebuffer,
+   &st_update_clear_color,
+   &st_update_depth,
+   &st_update_clip,
+   &st_update_vs,
+   &st_update_fs,
+   &st_update_setup,
+   &st_update_polygon_stipple,
+   &st_update_viewport,
+   &st_update_scissor,
+   &st_update_blend,
+   &st_update_stencil,
+   /* will be patched out at runtime */
+/*    &st_update_constants */
+};
+
+
+void st_init_atoms( struct st_context *st )
+{
+   GLuint i;
+
+   st->atoms = malloc(sizeof(atoms));
+   st->nr_atoms = sizeof(atoms)/sizeof(*atoms);
+   memcpy(st->atoms, atoms, sizeof(atoms));
+
+   /* Patch in a pointer to the dynamic state atom:
+    */
+   for (i = 0; i < st->nr_atoms; i++)
+      if (st->atoms[i] == &st_update_constants)
+        st->atoms[i] = &st->constants.tracked_state;
+
+   memcpy(&st->constants.tracked_state, 
+          &st_update_constants,
+          sizeof(st_update_constants));
+}
+
+
+void st_destroy_atoms( struct st_context *st )
+{
+   if (st->atoms) {
+      free(st->atoms);
+      st->atoms = NULL;
+   }
+}
+
+
+/***********************************************************************
+ */
+
+static GLboolean check_state( const struct st_state_flags *a,
+                             const struct st_state_flags *b )
+{
+   return ((a->mesa & b->mesa) ||
+          (a->st & b->st));
+}
+
+static void accumulate_state( struct st_state_flags *a,
+                             const struct st_state_flags *b )
+{
+   a->mesa |= b->mesa;
+   a->st |= b->st;
+}
+
+
+static void xor_states( struct st_state_flags *result,
+                            const struct st_state_flags *a,
+                             const struct st_state_flags *b )
+{
+   result->mesa = a->mesa ^ b->mesa;
+   result->st = a->st ^ b->st;
+}
+
+
+/***********************************************************************
+ * Update all derived state:
+ */
+
+void st_validate_state( struct st_context *st )
+{
+   struct st_state_flags *state = &st->dirty;
+   GLuint i;
+
+   if (state->st == 0)
+      return;
+
+   if (1) {
+      /* Debug version which enforces various sanity checks on the
+       * state flags which are generated and checked to help ensure
+       * state atoms are ordered correctly in the list.
+       */
+      struct st_state_flags examined, prev;      
+      memset(&examined, 0, sizeof(examined));
+      prev = *state;
+
+      for (i = 0; i < st->nr_atoms; i++) {      
+        const struct st_tracked_state *atom = st->atoms[i];
+        struct st_state_flags generated;
+
+        assert(atom->dirty.mesa ||
+               atom->dirty.st);
+        assert(atom->update);
+
+        if (check_state(state, &atom->dirty)) {
+           st->atoms[i]->update( st );
+        }
+
+        accumulate_state(&examined, &atom->dirty);
+
+        /* generated = (prev ^ state)
+         * if (examined & generated)
+         *     fail;
+         */
+        xor_states(&generated, &prev, state);
+        assert(!check_state(&examined, &generated));
+        prev = *state;
+      }
+   }
+   else {
+      const GLuint nr = st->nr_atoms;
+
+      for (i = 0; i < nr; i++) {        
+        if (check_state(state, &st->atoms[i]->dirty))
+           st->atoms[i]->update( st );
+      }
+   }
+
+   memset(state, 0, sizeof(*state));
+}
+
+
+
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
new file mode 100644 (file)
index 0000000..1b70e27
--- /dev/null
@@ -0,0 +1,62 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+    
+
+#ifndef ST_ATOM_H
+#define ST_ATOM_H
+
+struct st_context;
+struct st_tracked_state;
+
+void st_init_atoms( struct st_context *st );
+void st_destroy_atoms( struct st_context *st );
+
+
+void st_validate_state( struct st_context *st );
+
+
+const struct st_tracked_state st_update_framebuffer;
+const struct st_tracked_state st_update_clip;
+const struct st_tracked_state st_update_clear_color;
+const struct st_tracked_state st_update_depth;
+const struct st_tracked_state st_update_fs;
+const struct st_tracked_state st_update_vs;
+const struct st_tracked_state st_update_setup;
+const struct st_tracked_state st_update_polygon_stipple;
+const struct st_tracked_state st_update_viewport;
+const struct st_tracked_state st_update_constants;
+const struct st_tracked_state st_update_scissor;
+const struct st_tracked_state st_update_blend;
+const struct st_tracked_state st_update_stencil;
+
+
+#endif
diff --git a/src/mesa/state_tracker/st_atom_alphatest.c b/src/mesa/state_tracker/st_atom_alphatest.c
new file mode 100644 (file)
index 0000000..1e2e449
--- /dev/null
@@ -0,0 +1,94 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Brian Paul
+  */
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+
+
+/**
+ * Convert GLenum stencil func tokens to pipe tokens.
+ */
+static GLuint
+gl_alpha_func_to_sp(GLenum func)
+{
+   /* Same values, just biased */
+   assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER);
+   assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER);
+   assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER);
+   assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER);
+   assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER);
+   assert(func >= GL_NEVER);
+   assert(func <= GL_ALWAYS);
+   return func - GL_NEVER;
+}
+
+
+static void 
+update_alpha_test( struct st_context *st )
+{
+   struct pipe_alpha_test_state alpha;
+
+   memset(&alpha, 0, sizeof(alpha));
+
+   if (st->ctx->Color.AlphaEnabled) {
+      alpha.enabled = 1;
+      alpha.func = gl_alpha_func_to_sp(st->ctx->Color.AlphaFunc);
+      alpha.ref = st->ctx->Color.AlphaRef;
+   }
+
+   if (memcmp(&alpha, &st->state.alpha_test, sizeof(alpha)) != 0) {
+      /* state has changed */
+      st->state.alpha_test = alpha;  /* struct copy */
+      st->pipe->set_alpha_test_state(st->pipe, &alpha); /* set new state */
+   }
+}
+
+
+const struct st_tracked_state st_update_alpha_test = {
+   .dirty = {
+      .mesa = (_NEW_COLOR),
+      .st  = 0,
+   },
+   .update = update_alpha_test
+};
+
+
+
+
+
diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c
new file mode 100644 (file)
index 0000000..256f134
--- /dev/null
@@ -0,0 +1,240 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Brian Paul
+  */
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+
+
+/**
+ * Convert GLenum blend tokens to pipe tokens.
+ * Both blend factors and blend funcs are accepted.
+ */
+static GLuint
+gl_blend_to_sp(GLenum blend)
+{
+   switch (blend) {
+   /* blend functions */
+   case GL_FUNC_ADD:
+      return PIPE_BLEND_ADD;
+   case GL_FUNC_SUBTRACT:
+      return PIPE_BLEND_SUBTRACT;
+   case GL_FUNC_REVERSE_SUBTRACT:
+      return PIPE_BLEND_REVERSE_SUBTRACT;
+   case GL_MIN:
+      return PIPE_BLEND_MIN;
+   case GL_MAX:
+      return PIPE_BLEND_MAX;
+
+   /* blend factors */
+   case GL_ONE:
+      return PIPE_BLENDFACTOR_ONE;
+   case GL_SRC_COLOR:
+      return PIPE_BLENDFACTOR_SRC_COLOR;
+   case GL_SRC_ALPHA:
+      return PIPE_BLENDFACTOR_SRC_ALPHA;
+   case GL_DST_ALPHA:
+      return PIPE_BLENDFACTOR_DST_ALPHA;
+   case GL_DST_COLOR:
+      return PIPE_BLENDFACTOR_DST_COLOR;
+   case GL_SRC_ALPHA_SATURATE:
+      return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;
+   case GL_CONSTANT_COLOR:
+      return PIPE_BLENDFACTOR_CONST_COLOR;
+   case GL_CONSTANT_ALPHA:
+      return PIPE_BLENDFACTOR_CONST_ALPHA;
+      /*
+      return PIPE_BLENDFACTOR_SRC1_COLOR;
+      return PIPE_BLENDFACTOR_SRC1_ALPHA;
+      */
+   case GL_ZERO:
+      return PIPE_BLENDFACTOR_ZERO;
+   case GL_ONE_MINUS_SRC_COLOR:
+      return PIPE_BLENDFACTOR_INV_SRC_COLOR;
+   case GL_ONE_MINUS_SRC_ALPHA:
+      return PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+   case GL_ONE_MINUS_DST_COLOR:
+      return PIPE_BLENDFACTOR_INV_DST_ALPHA;
+   case GL_ONE_MINUS_DST_ALPHA:
+      return PIPE_BLENDFACTOR_INV_DST_COLOR;
+   case GL_ONE_MINUS_CONSTANT_COLOR:
+      return PIPE_BLENDFACTOR_INV_CONST_COLOR;
+   case GL_ONE_MINUS_CONSTANT_ALPHA:
+      return PIPE_BLENDFACTOR_INV_CONST_ALPHA;
+      /*
+      return PIPE_BLENDFACTOR_INV_SRC1_COLOR;
+      return PIPE_BLENDFACTOR_INV_SRC1_ALPHA;
+      */
+   default:
+      assert("invalid GL token in gl_blend_to_sp()" == NULL);
+      return 0;
+   }
+}
+
+
+/**
+ * Convert GLenum logicop tokens to pipe tokens.
+ */
+static GLuint
+gl_logicop_to_sp(GLenum logicop)
+{
+   switch (logicop) {
+   case GL_CLEAR:
+      return PIPE_LOGICOP_CLEAR;
+   case GL_NOR:
+      return PIPE_LOGICOP_NOR;
+   case GL_AND_INVERTED:
+      return PIPE_LOGICOP_AND_INVERTED;
+   case GL_COPY_INVERTED:
+      return PIPE_LOGICOP_COPY_INVERTED;
+   case GL_AND_REVERSE:
+      return PIPE_LOGICOP_AND_REVERSE;
+   case GL_INVERT:
+      return PIPE_LOGICOP_INVERT;
+   case GL_XOR:
+      return PIPE_LOGICOP_XOR;
+   case GL_NAND:
+      return PIPE_LOGICOP_NAND;
+   case GL_AND:
+      return PIPE_LOGICOP_AND;
+   case GL_EQUIV:
+      return PIPE_LOGICOP_EQUIV;
+   case GL_NOOP:
+      return PIPE_LOGICOP_NOOP;
+   case GL_OR_INVERTED:
+      return PIPE_LOGICOP_OR_INVERTED;
+   case GL_COPY:
+      return PIPE_LOGICOP_COPY;
+   case GL_OR_REVERSE:
+      return PIPE_LOGICOP_OR_REVERSE;
+   case GL_OR:
+      return PIPE_LOGICOP_OR;
+   case GL_SET:
+      return PIPE_LOGICOP_SET;
+   default:
+      assert("invalid GL token in gl_logicop_to_sp()" == NULL);
+      return 0;
+   }
+}
+
+
+static void 
+update_blend( struct st_context *st )
+{
+   struct pipe_blend_state blend;
+
+   memset(&blend, 0, sizeof(blend));
+
+   if (st->ctx->Color.ColorLogicOpEnabled ||
+       (st->ctx->Color.BlendEnabled &&
+        st->ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) {
+      /* logicop enabled */
+      blend.logicop_enable = 1;
+      blend.logicop_func = gl_logicop_to_sp(st->ctx->Color.LogicOp);
+   }
+   else if (st->ctx->Color.BlendEnabled) {
+      /* blending enabled */
+      blend.blend_enable = 1;
+
+      blend.rgb_func = gl_blend_to_sp(st->ctx->Color.BlendEquationRGB);
+      if (st->ctx->Color.BlendEquationRGB == GL_MIN ||
+          st->ctx->Color.BlendEquationRGB == GL_MAX) {
+         /* Min/max are special */
+         blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+         blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+      }
+      else {
+         blend.rgb_src_factor = gl_blend_to_sp(st->ctx->Color.BlendSrcRGB);
+         blend.rgb_dst_factor = gl_blend_to_sp(st->ctx->Color.BlendDstRGB);
+      }
+
+      blend.alpha_func = gl_blend_to_sp(st->ctx->Color.BlendEquationA);
+      if (st->ctx->Color.BlendEquationA == GL_MIN ||
+          st->ctx->Color.BlendEquationA == GL_MAX) {
+         /* Min/max are special */
+         blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+         blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+      }
+      else {
+         blend.alpha_src_factor = gl_blend_to_sp(st->ctx->Color.BlendSrcA);
+         blend.alpha_dst_factor = gl_blend_to_sp(st->ctx->Color.BlendDstA);
+      }
+   }
+   else {
+      /* no blending / logicop */
+   }
+
+   /* Colormask - maybe reverse these bits? */
+   if (st->ctx->Color.ColorMask[0])
+      blend.colormask |= PIPE_MASK_R;
+   if (st->ctx->Color.ColorMask[1])
+      blend.colormask |= PIPE_MASK_G;
+   if (st->ctx->Color.ColorMask[2])
+      blend.colormask |= PIPE_MASK_B;
+   if (st->ctx->Color.ColorMask[3])
+      blend.colormask |= PIPE_MASK_A;
+
+   if (st->ctx->Color.DitherFlag)
+      blend.dither = 1;
+
+   if (memcmp(&blend, &st->state.blend, sizeof(blend)) != 0) {
+      /* state has changed */
+      st->state.blend = blend;  /* struct copy */
+      st->pipe->set_blend_state(st->pipe, &blend); /* set new state */
+   }
+
+   if (memcmp(st->ctx->Color.BlendColor, &st->state.blend_color, 4 * sizeof(GLfloat)) != 0) {
+      /* state has changed */
+      st->state.blend_color.color[0] = st->ctx->Color.BlendColor[0];
+      st->state.blend_color.color[1] = st->ctx->Color.BlendColor[1];
+      st->state.blend_color.color[2] = st->ctx->Color.BlendColor[2];
+      st->state.blend_color.color[3] = st->ctx->Color.BlendColor[3];
+      st->pipe->set_blend_color(st->pipe, (struct pipe_blend_color *) st->ctx->Color.BlendColor);
+   }
+}
+
+
+const struct st_tracked_state st_update_blend = {
+   .dirty = {
+      .mesa = (_NEW_COLOR),  /* XXX _NEW_BLEND someday? */
+      .st  = 0,
+   },
+   .update = update_blend
+};
+
+
+
+
+
diff --git a/src/mesa/state_tracker/st_atom_cbuf.c b/src/mesa/state_tracker/st_atom_cbuf.c
new file mode 100644 (file)
index 0000000..0f90aa7
--- /dev/null
@@ -0,0 +1,72 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+#include "st_context.h"
+#include "pipe/p_context.h"
+#include "st_atom.h"
+
+extern GLboolean xmesa_get_cbuf_details( GLcontext *ctx,
+                                        void **ptr,
+                                        GLuint *cpp,
+                                        GLint *stride,
+                                        GLuint *format );
+
+
+/* This is a hack to work with the X11 driver as a test harness
+ */
+static void update_cbuf_state( struct st_context *st )
+{
+   struct pipe_surface cbuf;
+   GLboolean ok;
+
+   ok = xmesa_get_cbuf_details( st->ctx,
+                               (void **)&cbuf.ptr,
+                               &cbuf.cpp,
+                               &cbuf.stride,
+                               &cbuf.format );
+
+   assert(ok);
+
+   if (memcmp(&cbuf, &st->state.cbuf, sizeof(cbuf)) != 0) {
+      st->state.cbuf = cbuf;
+      st->pipe->set_cbuf_state( st->pipe, &cbuf );
+   }
+}
+
+const struct st_tracked_state st_update_cbuf = {
+   .dirty = {
+      .mesa = _NEW_BUFFERS,
+      .st  = 0,
+   },
+   .update = update_cbuf_state
+};
+
diff --git a/src/mesa/state_tracker/st_atom_clear_color.c b/src/mesa/state_tracker/st_atom_clear_color.c
new file mode 100644 (file)
index 0000000..adf730c
--- /dev/null
@@ -0,0 +1,62 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Brian Paul
+  */
+#include "st_context.h"
+#include "st_atom.h"
+#include "pipe/p_context.h"
+
+
+static void
+update_clear_color_state( struct st_context *st )
+{
+   struct pipe_clear_color_state clear;
+
+   clear.color[0] = st->ctx->Color.ClearColor[0];
+   clear.color[1] = st->ctx->Color.ClearColor[1];
+   clear.color[2] = st->ctx->Color.ClearColor[2];
+   clear.color[3] = st->ctx->Color.ClearColor[3];
+
+   if (memcmp(&clear, &st->state.clear_color, sizeof(clear)) != 0) {
+      st->state.clear_color = clear;
+      st->pipe->set_clear_color_state( st->pipe, &clear );
+   }
+}
+
+
+const struct st_tracked_state st_update_clear_color = {
+   .dirty = {
+      .mesa = _NEW_COLOR,
+      .st  = 0,
+   },
+   .update = update_clear_color_state
+};
diff --git a/src/mesa/state_tracker/st_atom_clip.c b/src/mesa/state_tracker/st_atom_clip.c
new file mode 100644 (file)
index 0000000..8ccad63
--- /dev/null
@@ -0,0 +1,75 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "st_context.h"
+#include "pipe/p_context.h"
+#include "st_atom.h"
+
+
+/* Second state atom for user clip planes:
+ */
+static void update_clip( struct st_context *st )
+{
+   struct pipe_clip_state clip;
+   GLuint i;
+
+   memset(&clip, 0, sizeof(clip));
+
+   for (i = 0; i < PIPE_MAX_CLIP_PLANES; i++) {
+      if (st->ctx->Transform.ClipPlanesEnabled & (1 << i)) {
+        memcpy(clip.ucp[clip.nr], 
+               st->ctx->Transform._ClipUserPlane[i], 
+               sizeof(clip.ucp[0]));
+        clip.nr++;
+      }
+   }
+      
+   if (memcmp(&clip, &st->state.clip, sizeof(clip)) != 0) {
+      st->state.clip = clip;
+      st->pipe->set_clip_state(st->pipe, &clip);
+   }
+}
+
+
+const struct st_tracked_state st_update_clip = {
+   .dirty = {
+      .mesa = (_NEW_TRANSFORM),
+      .st  = 0,
+   },
+   .update = update_clip
+};
+
+
+
+
+
diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c
new file mode 100644 (file)
index 0000000..7fc5195
--- /dev/null
@@ -0,0 +1,92 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Brian Paul
+  */
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+
+
+/**
+ * Convert GLenum depth func tokens to pipe tokens.
+ */
+static GLuint
+gl_depth_func_to_sp(GLenum func)
+{
+   /* Same values, just biased */
+   assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER);
+   assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER);
+   assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER);
+   assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER);
+   assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER);
+   assert(func >= GL_NEVER);
+   assert(func <= GL_ALWAYS);
+   return func - GL_NEVER;
+}
+
+
+static void 
+update_depth( struct st_context *st )
+{
+   struct pipe_depth_state depth;
+
+   memset(&depth, 0, sizeof(depth));
+
+   depth.enabled = st->ctx->Depth.Test;
+   depth.writemask = st->ctx->Depth.Mask;
+   depth.func = gl_depth_func_to_sp(st->ctx->Depth.Func);
+   depth.clear = st->ctx->Depth.Clear;
+
+   if (st->ctx->Query.CurrentOcclusionObject &&
+       st->ctx->Query.CurrentOcclusionObject->Active)
+      depth.occlusion_count = 1;
+
+   if (memcmp(&depth, &st->state.depth, sizeof(depth)) != 0) {
+      /* state has changed */
+      st->state.depth = depth;  /* struct copy */
+      st->pipe->set_depth_state(st->pipe, &depth); /* set new state */
+   }
+}
+
+
+const struct st_tracked_state st_update_depth = {
+   .dirty = {
+      .mesa = (_NEW_DEPTH),
+      .st  = 0,
+   },
+   .update = update_depth
+};
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
new file mode 100644 (file)
index 0000000..a8d47ea
--- /dev/null
@@ -0,0 +1,88 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Brian Paul
+  */
+#include "st_context.h"
+#include "st_atom.h"
+#include "pipe/p_context.h"
+
+
+/**
+ * Update framebuffer state (color, depth, stencil, etc. buffers)
+ * XXX someday: separate draw/read buffers.
+ */
+static void
+update_framebuffer_state( struct st_context *st )
+{
+   struct pipe_framebuffer_state framebuffer;
+   struct gl_renderbuffer *rb;
+   GLuint i;
+
+   memset(&framebuffer, 0, sizeof(framebuffer));
+
+   /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state
+    * to determine which surfaces to draw to
+    */
+   framebuffer.num_cbufs = st->ctx->DrawBuffer->_NumColorDrawBuffers[0];
+   for (i = 0; i < framebuffer.num_cbufs; i++) {
+      rb = st->ctx->DrawBuffer->_ColorDrawBuffers[0][i];
+      assert(rb->surface);
+      framebuffer.cbufs[i] = rb->surface;
+   }
+
+   rb = st->ctx->DrawBuffer->_DepthBuffer;
+   if (rb) {
+      assert(rb->surface);
+      framebuffer.zbuf = rb->Wrapped->surface;
+   }
+
+   rb = st->ctx->DrawBuffer->_StencilBuffer;
+   if (rb) {
+      assert(rb->surface);
+      framebuffer.sbuf = rb->Wrapped->surface;
+   }
+
+   if (memcmp(&framebuffer, &st->state.framebuffer, sizeof(framebuffer)) != 0) {
+      st->state.framebuffer = framebuffer;
+      st->pipe->set_framebuffer_state( st->pipe, &framebuffer );
+   }
+}
+
+
+const struct st_tracked_state st_update_framebuffer = {
+   .dirty = {
+      .mesa = _NEW_BUFFERS,
+      .st  = 0,
+   },
+   .update = update_framebuffer_state
+};
+
diff --git a/src/mesa/state_tracker/st_atom_fs.c b/src/mesa/state_tracker/st_atom_fs.c
new file mode 100644 (file)
index 0000000..9ca1807
--- /dev/null
@@ -0,0 +1,102 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+                   
+#include "shader/prog_parameter.h"
+#include "st_context.h"
+#include "pipe/p_context.h"
+#include "st_atom.h"
+#include "st_program.h"
+#include "pipe/tgsi/mesa/mesa_to_tgsi.h"
+#include "pipe/tgsi/core/tgsi_dump.h"
+
+static void compile_fs( struct st_context *st,
+                       struct st_fragment_program *fs )
+{
+   /* XXX: fix static allocation of tokens:
+    */
+   tgsi_mesa_compile_fp_program( &fs->Base, fs->tokens, ST_FP_MAX_TOKENS );
+
+   tgsi_dump( fs->tokens, TGSI_DUMP_VERBOSE );
+}
+
+
+static void update_fs( struct st_context *st )
+{
+   struct pipe_fs_state fs;
+   struct st_fragment_program *fp = NULL;
+   struct gl_program_parameter_list *params = NULL;
+
+   if (st->ctx->Shader.CurrentProgram &&
+       st->ctx->Shader.CurrentProgram->LinkStatus &&
+       st->ctx->Shader.CurrentProgram->FragmentProgram) {
+      struct gl_fragment_program *f
+         = st->ctx->Shader.CurrentProgram->FragmentProgram;
+      fp = st_fragment_program(f);
+      params = f->Base.Parameters;
+   }
+   else if (st->ctx->FragmentProgram._Current) {
+      fp = st_fragment_program(st->ctx->FragmentProgram._Current);
+      params = st->ctx->FragmentProgram._Current->Base.Parameters;
+   }
+
+   if (fp && params) {
+      /* load program's constants array */
+      fp->constants.nr_constants = params->NumParameters;
+      memcpy(fp->constants.constant, 
+             params->ParameterValues,
+             params->NumParameters * sizeof(GLfloat) * 4);
+   }
+
+   if (fp->dirty)
+      compile_fs( st, fp );
+
+   memset( &fs, 0, sizeof(fs) );
+   fs.inputs_read = fp->Base.Base.InputsRead;
+   fs.tokens = &fp->tokens[0];
+   fs.constants = &fp->constants;
+   
+   if (memcmp(&fs, &st->state.fs, sizeof(fs)) != 0 ||
+       fp->dirty) 
+   {
+      fp->dirty = 0;
+      st->state.fs = fs;
+      st->pipe->set_fs_state(st->pipe, &fs);
+   }
+}
+
+
+const struct st_tracked_state st_update_fs = {
+   .dirty = {
+      .mesa  = _NEW_PROGRAM,
+      .st   = ST_NEW_FRAGMENT_PROGRAM,
+   },
+   .update = update_fs
+};
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
new file mode 100644 (file)
index 0000000..1aa9da8
--- /dev/null
@@ -0,0 +1,135 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Brian Paul
+  */
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+
+
+/**
+ * Convert GLenum texcoord wrap tokens to pipe tokens.
+ */
+static GLuint
+gl_wrap_to_sp(GLenum wrap)
+{
+   switch (wrap) {
+   case GL_REPEAT:
+      return PIPE_TEX_WRAP_REPEAT;
+   case GL_CLAMP:
+      return PIPE_TEX_WRAP_CLAMP;
+   case GL_CLAMP_TO_EDGE:
+      return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   case GL_CLAMP_TO_BORDER:
+      return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
+   case GL_MIRRORED_REPEAT:
+      return PIPE_TEX_WRAP_MIRROR_REPEAT;
+   case GL_MIRROR_CLAMP_EXT:
+      return PIPE_TEX_WRAP_MIRROR_CLAMP;
+   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
+      return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
+   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
+      return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER;
+   default:
+      abort();
+      return 0;
+   }
+}
+
+
+static GLuint
+gl_filter_to_sp(GLenum filter)
+{
+   switch (filter) {
+   case GL_NEAREST:
+      return PIPE_TEX_FILTER_NEAREST;
+   case GL_LINEAR:
+      return PIPE_TEX_FILTER_LINEAR;
+   case GL_NEAREST_MIPMAP_NEAREST:
+      return PIPE_TEX_FILTER_NEAREST_MIPMAP_NEAREST;
+   case GL_NEAREST_MIPMAP_LINEAR:
+      return PIPE_TEX_FILTER_NEAREST_MIPMAP_LINEAR;
+   case GL_LINEAR_MIPMAP_NEAREST:
+      return PIPE_TEX_FILTER_LINEAR_MIPMAP_NEAREST;
+   case GL_LINEAR_MIPMAP_LINEAR:
+      return PIPE_TEX_FILTER_LINEAR_MIPMAP_LINEAR;
+   default:
+      abort();
+      return 0;
+   }
+}
+
+
+static void 
+update_samplers(struct st_context *st)
+{
+   GLuint u;
+
+   for (u = 0; u < st->ctx->Const.MaxTextureImageUnits; u++) {
+      const struct gl_texture_object *texobj
+         = st->ctx->Texture.Unit[u]._Current;
+      struct pipe_sampler_state sampler;
+
+      memset(&sampler, 0, sizeof(sampler));
+
+      sampler.wrap_s = gl_wrap_to_sp(texobj->WrapS);
+      sampler.wrap_t = gl_wrap_to_sp(texobj->WrapT);
+      sampler.wrap_r = gl_wrap_to_sp(texobj->WrapR);
+
+      sampler.min_filter = gl_filter_to_sp(texobj->MinFilter);
+      sampler.mag_filter = gl_filter_to_sp(texobj->MagFilter);
+
+      /* XXX more sampler state here */
+
+      if (memcmp(&sampler, &st->state.sampler[u], sizeof(sampler)) != 0) {
+         /* state has changed */
+         st->state.sampler[u] = sampler;
+         st->pipe->set_sampler_state(st->pipe, u, &sampler);
+      }
+   }
+}
+
+
+const struct st_tracked_state st_update_sampler = {
+   .dirty = {
+      .mesa = _NEW_TEXTURE,
+      .st  = 0,
+   },
+   .update = update_samplers
+};
+
+
+
+
+
diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c
new file mode 100644 (file)
index 0000000..05a9f3e
--- /dev/null
@@ -0,0 +1,88 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "st_context.h"
+#include "pipe/p_context.h"
+#include "st_atom.h"
+
+
+/**
+ * Scissor depends on the scissor box, and the framebuffer dimensions.
+ */
+static void
+update_scissor( struct st_context *st )
+{
+   struct pipe_scissor_state scissor;
+   const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
+
+   scissor.minx = 0;
+   scissor.miny = 0;
+   scissor.maxx = fb->Width;
+   scissor.maxy = fb->Height;
+
+   if (st->ctx->Scissor.Enabled) {
+      if (st->ctx->Scissor.X > scissor.minx)
+         scissor.minx = st->ctx->Scissor.X;
+      if (st->ctx->Scissor.Y > scissor.miny)
+         scissor.miny = st->ctx->Scissor.Y;
+
+      if (st->ctx->Scissor.X + st->ctx->Scissor.Width < scissor.maxx)
+         scissor.maxx = st->ctx->Scissor.X + st->ctx->Scissor.Width;
+      if (st->ctx->Scissor.Y + st->ctx->Scissor.Height < scissor.maxy)
+         scissor.maxy = st->ctx->Scissor.Y + st->ctx->Scissor.Height;
+
+      /* check for null space */
+      if (scissor.minx >= scissor.maxx || scissor.miny >= scissor.maxy)
+         scissor.minx = scissor.miny = scissor.maxx = scissor.maxy = 0;
+   }
+
+   if (memcmp(&scissor, &st->state.scissor, sizeof(scissor)) != 0) {
+      /* state has changed */
+      st->state.scissor = scissor;  /* struct copy */
+      st->pipe->set_scissor_state(st->pipe, &scissor); /* activate */
+   }
+}
+
+
+const struct st_tracked_state st_update_scissor = {
+   .dirty = {
+      .mesa = (_NEW_SCISSOR | _NEW_BUFFERS),
+      .st  = 0,
+   },
+   .update = update_scissor
+};
+
+
+
+
+
diff --git a/src/mesa/state_tracker/st_atom_setup.c b/src/mesa/state_tracker/st_atom_setup.c
new file mode 100644 (file)
index 0000000..3eac258
--- /dev/null
@@ -0,0 +1,220 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "st_context.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "st_atom.h"
+
+static GLuint translate_fill( GLenum mode )
+{
+   switch (mode) {
+   case GL_POINT:
+      return PIPE_POLYGON_MODE_POINT;
+   case GL_LINE:
+      return PIPE_POLYGON_MODE_LINE;
+   case GL_FILL:
+      return PIPE_POLYGON_MODE_FILL;
+   default:
+      assert(0);
+      return 0;
+   }
+}
+
+static GLboolean get_offset_flag( GLuint fill_mode, 
+                                 const struct gl_polygon_attrib *p )
+{
+   switch (fill_mode) {
+   case PIPE_POLYGON_MODE_POINT:
+      return p->OffsetPoint;
+   case PIPE_POLYGON_MODE_LINE:
+      return p->OffsetLine;
+   case PIPE_POLYGON_MODE_FILL:
+      return p->OffsetFill;
+   default:
+      assert(0);
+      return 0;
+   }
+}
+
+
+static void update_setup_state( struct st_context *st )
+{
+   GLcontext *ctx = st->ctx;
+   struct pipe_setup_state setup;
+
+   memset(&setup, 0, sizeof(setup));
+   
+   /* _NEW_POLYGON, _NEW_BUFFERS
+    */
+   {
+      if (ctx->Polygon.FrontFace == GL_CCW)
+         setup.front_winding = PIPE_WINDING_CCW;
+      else
+         setup.front_winding = PIPE_WINDING_CW;
+
+      /* XXX
+       * I think the intention here is that user-created framebuffer objects
+       * use Y=0=TOP layout instead of OpenGL's normal Y=0=bottom layout.
+       * Flipping Y changes CW to CCW and vice-versa.
+       * But this is an implementation/driver-specific artifact - remove...
+       */
+      if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0)
+         setup.front_winding ^= PIPE_WINDING_BOTH;
+   }
+
+   /* _NEW_LIGHT
+    */
+   if (ctx->Light.ShadeModel == GL_FLAT)
+      setup.flatshade = 1;
+
+   /* _NEW_LIGHT | _NEW_PROGRAM
+    *
+    * Back-face colors can come from traditional lighting (when
+    * GL_LIGHT_MODEL_TWO_SIDE is set) or from vertex programs (when
+    * GL_VERTEX_PROGRAM_TWO_SIDE is set).  Note the logic here.
+    */
+   if (ctx->VertexProgram._Enabled) {
+      setup.light_twoside = ctx->VertexProgram.TwoSideEnabled;
+   }
+   else if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
+      setup.light_twoside = 1;
+   }
+
+   /* _NEW_POLYGON
+    */
+   if (ctx->Polygon.CullFlag) {
+      if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
+        setup.cull_mode = PIPE_WINDING_BOTH;
+      }
+      else if (ctx->Polygon.CullFaceMode == GL_FRONT) {
+        setup.cull_mode = setup.front_winding;
+      }
+      else {
+        setup.cull_mode = setup.front_winding ^ PIPE_WINDING_BOTH;
+      }
+   }
+
+   /* _NEW_POLYGON
+    */
+   {
+      GLuint fill_front = translate_fill( ctx->Polygon.FrontMode );
+      GLuint fill_back = translate_fill( ctx->Polygon.BackMode );
+      
+      if (setup.front_winding == PIPE_WINDING_CW) {
+        setup.fill_cw = fill_front;
+        setup.fill_ccw = fill_back;
+      }
+      else {
+        setup.fill_cw = fill_back;
+        setup.fill_ccw = fill_front;
+      }
+
+      /* Simplify when culling is active:
+       */
+      if (setup.cull_mode & PIPE_WINDING_CW) {
+        setup.fill_cw = setup.fill_ccw;
+      }
+      
+      if (setup.cull_mode & PIPE_WINDING_CCW) {
+        setup.fill_ccw = setup.fill_cw;
+      }
+   }
+
+   /* _NEW_POLYGON 
+    */
+   if (ctx->Polygon.OffsetUnits != 0.0 ||
+       ctx->Polygon.OffsetFactor != 0.0) {
+      setup.offset_cw = get_offset_flag( setup.fill_cw, &ctx->Polygon );
+      setup.offset_ccw = get_offset_flag( setup.fill_ccw, &ctx->Polygon );
+      setup.offset_units = ctx->Polygon.OffsetUnits;
+      setup.offset_scale = ctx->Polygon.OffsetFactor;
+   }
+
+   if (ctx->Polygon.SmoothFlag)
+      setup.poly_smooth = 1;
+
+   if (ctx->Polygon.StippleFlag)
+      setup.poly_stipple_enable = 1;
+
+
+   /* _NEW_BUFFERS, _NEW_POLYGON
+    */
+   if (setup.fill_cw != PIPE_POLYGON_MODE_FILL ||
+       setup.fill_ccw != PIPE_POLYGON_MODE_FILL)
+   {
+      GLfloat mrd = (ctx->DrawBuffer ? 
+                    ctx->DrawBuffer->_MRD : 
+                    1.0);
+
+      setup.offset_units = ctx->Polygon.OffsetFactor * mrd;
+      setup.offset_scale = (ctx->Polygon.OffsetUnits * mrd *
+                           st->polygon_offset_scale);
+   }
+      
+   /* _NEW_POINT
+    */
+   setup.point_size = ctx->Point.Size;
+   setup.point_smooth = ctx->Point.SmoothFlag;
+
+   /* _NEW_LINE
+    */
+   setup.line_width = ctx->Line.Width;
+   setup.line_smooth = ctx->Line.SmoothFlag;
+   setup.line_stipple_enable = ctx->Line.StippleFlag;
+   setup.line_stipple_pattern = ctx->Line.StipplePattern;
+   /* GL stipple factor is in [1,256], remap to [0, 255] here */
+   setup.line_stipple_factor = ctx->Line.StippleFactor - 1;
+
+   /* _NEW_MULTISAMPLE */
+   if (ctx->Multisample.Enabled)
+      setup.multisample = 1;
+
+   /* _NEW_SCISSOR */
+   if (ctx->Scissor.Enabled)
+      setup.scissor = 1;
+
+   if (memcmp(&setup, &st->state.setup, sizeof(setup)) != 0) {
+      st->state.setup = setup;
+      st->pipe->set_setup_state( st->pipe, &setup );
+   }
+}
+
+const struct st_tracked_state st_update_setup = {
+   .dirty = {
+      .mesa = (_NEW_LIGHT | _NEW_POLYGON | _NEW_LINE | _NEW_SCISSOR |
+               _NEW_POINT | _NEW_BUFFERS | _NEW_MULTISAMPLE),
+      .st  = 0,
+   },
+   .update = update_setup_state
+};
diff --git a/src/mesa/state_tracker/st_atom_stencil.c b/src/mesa/state_tracker/st_atom_stencil.c
new file mode 100644 (file)
index 0000000..d037335
--- /dev/null
@@ -0,0 +1,140 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Brian Paul
+  */
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+
+
+/**
+ * Convert GLenum stencil func tokens to pipe tokens.
+ */
+static GLuint
+gl_stencil_func_to_sp(GLenum func)
+{
+   /* Same values, just biased */
+   assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER);
+   assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER);
+   assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER);
+   assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER);
+   assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER);
+   assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER);
+   assert(func >= GL_NEVER);
+   assert(func <= GL_ALWAYS);
+   return func - GL_NEVER;
+}
+
+
+/**
+ * Convert GLenum stencil op tokens to pipe tokens.
+ */
+static GLuint
+gl_stencil_op_to_sp(GLenum func)
+{
+   switch (func) {
+   case GL_KEEP:
+      return PIPE_STENCIL_OP_KEEP;
+   case GL_ZERO:
+      return PIPE_STENCIL_OP_ZERO;
+   case GL_REPLACE:
+      return PIPE_STENCIL_OP_REPLACE;
+   case GL_INCR:
+      return PIPE_STENCIL_OP_INCR;
+   case GL_DECR:
+      return PIPE_STENCIL_OP_DECR;
+   case GL_INCR_WRAP:
+      return PIPE_STENCIL_OP_INCR_WRAP;
+   case GL_DECR_WRAP:
+      return PIPE_STENCIL_OP_DECR_WRAP;
+   case GL_INVERT:
+      return PIPE_STENCIL_OP_INVERT;
+   default:
+      assert("invalid GL token in gl_stencil_op_to_sp()" == NULL);
+      return 0;
+   }
+}
+
+
+static void 
+update_stencil( struct st_context *st )
+{
+   struct pipe_stencil_state stencil;
+
+   memset(&stencil, 0, sizeof(stencil));
+
+   if (st->ctx->Stencil.Enabled) {
+      stencil.front_enabled = 1;
+      stencil.front_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[0]);
+      stencil.front_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[0]);
+      stencil.front_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[0]);
+      stencil.front_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[0]);
+      stencil.ref_value[0] = st->ctx->Stencil.Ref[0] & 0xff;
+      stencil.value_mask[0] = st->ctx->Stencil.ValueMask[0] & 0xff;
+      stencil.write_mask[0] = st->ctx->Stencil.WriteMask[0] & 0xff;
+      if (st->ctx->Stencil.TestTwoSide) {
+         stencil.back_enabled = 1;
+         stencil.back_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[1]);
+         stencil.back_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[1]);
+         stencil.back_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[1]);
+         stencil.back_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[1]);
+         stencil.ref_value[1] = st->ctx->Stencil.Ref[1] & 0xff;
+         stencil.value_mask[1] = st->ctx->Stencil.ValueMask[1] & 0xff;
+         stencil.write_mask[1] = st->ctx->Stencil.WriteMask[1] & 0xff;
+      }
+      stencil.clear_value = st->ctx->Stencil.Clear & 0xff;
+   }
+
+   if (memcmp(&stencil, &st->state.stencil, sizeof(stencil)) != 0) {
+      /* state has changed */
+      st->state.stencil = stencil;  /* struct copy */
+      st->pipe->set_stencil_state(st->pipe, &stencil); /* set new state */
+   }
+}
+
+
+const struct st_tracked_state st_update_stencil = {
+   .dirty = {
+      .mesa = (_NEW_STENCIL),
+      .st  = 0,
+   },
+   .update = update_stencil
+};
+
+
+
+
+
diff --git a/src/mesa/state_tracker/st_atom_stipple.c b/src/mesa/state_tracker/st_atom_stipple.c
new file mode 100644 (file)
index 0000000..dd04d21
--- /dev/null
@@ -0,0 +1,62 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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.
+ * 
+ **************************************************************************/
+
+ /*
+  * \brief polygon stipple state
+  *
+  * Authors:
+  *   Brian Paul
+  */
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+
+
+static void 
+update_stipple( struct st_context *st )
+{
+   const GLuint sz = sizeof(st->state.poly_stipple.stipple);
+   assert(sz == sizeof(st->ctx->PolygonStipple));
+
+   if (memcmp(&st->state.poly_stipple.stipple, st->ctx->PolygonStipple, sz)) {
+      /* state has changed */
+      memcpy(st->state.poly_stipple.stipple, st->ctx->PolygonStipple, sz);
+      st->pipe->set_polygon_stipple(st->pipe, &st->state.poly_stipple);
+   }
+}
+
+
+const struct st_tracked_state st_update_polygon_stipple = {
+   .dirty = {
+      .mesa = (_NEW_POLYGONSTIPPLE),
+      .st  = 0,
+   },
+   .update = update_stipple
+};
diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c
new file mode 100644 (file)
index 0000000..ac91f62
--- /dev/null
@@ -0,0 +1,117 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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 "context.h"
+#include "colormac.h"
+#include "st_context.h"
+#include "pipe/p_context.h"
+#include "st_atom.h"
+
+
+
+
+
+/**
+ * Update the viewport transformation matrix.  Depends on:
+ *  - viewport pos/size
+ *  - depthrange
+ *  - window pos/size or FBO size
+ */
+static void update_viewport( struct st_context *st )
+{
+   GLcontext *ctx = st->ctx;
+   const GLframebuffer *DrawBuffer = ctx->DrawBuffer;
+   GLfloat yScale = 1.0;
+   GLfloat yBias = 0.0;
+
+   /* _NEW_BUFFERS
+    */
+   if (DrawBuffer) {
+
+#if 0
+      if (DrawBuffer->Name) {
+        /* User created FBO */
+        struct st_renderbuffer *irb
+           = st_renderbuffer(DrawBuffer->_ColorDrawBuffers[0][0]);
+        if (irb && !irb->RenderToTexture) {
+           /* y=0=top */
+           yScale = -1.0;
+           yBias = irb->Base.Height;
+        }
+        else {
+           /* y=0=bottom */
+           yScale = 1.0;
+           yBias = 0.0;
+        }
+      }
+      else 
+      {
+        /* window buffer, y=0=top */
+        yScale = -1.0;
+        yBias = DrawBuffer->Height;
+      }
+#endif
+   }
+
+   {
+      /* _NEW_VIEWPORT 
+       */
+      GLfloat x = ctx->Viewport.X;
+      GLfloat y = ctx->Viewport.Y;
+      GLfloat z = ctx->Viewport.Near;
+      GLfloat half_width = ctx->Viewport.Width / 2.0;
+      GLfloat half_height = ctx->Viewport.Height / 2.0;
+      GLfloat half_depth = (ctx->Viewport.Far - ctx->Viewport.Near) / 2.0;
+
+      struct pipe_viewport_state vp;
+      
+      vp.scale[0] = half_width;
+      vp.scale[1] = half_height * yScale;
+      vp.scale[2] = half_depth;
+      vp.scale[3] = 1.0;
+
+      vp.translate[0] = (half_width + x);
+      vp.translate[1] = (half_height + y) * yScale + yBias;
+      vp.translate[2] = (half_depth + z);
+      vp.translate[3] = 0.0;
+
+      if (memcmp(&vp, &st->state.viewport, sizeof(vp)) != 0) {
+        st->state.viewport = vp;
+        st->pipe->set_viewport_state(st->pipe, &vp);
+      }
+   }
+}
+
+
+const struct st_tracked_state st_update_viewport = {
+   .dirty = {
+      .mesa = _NEW_BUFFERS | _NEW_VIEWPORT,
+      .st = 0,
+   },
+   .update = update_viewport
+};
diff --git a/src/mesa/state_tracker/st_atom_vs.c b/src/mesa/state_tracker/st_atom_vs.c
new file mode 100644 (file)
index 0000000..6a26bfd
--- /dev/null
@@ -0,0 +1,49 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+                   
+#include "st_context.h"
+#include "pipe/p_context.h"
+#include "st_atom.h"
+
+
+static void update_vs( struct st_context *st )
+{
+}
+
+
+const struct st_tracked_state st_update_vs = {
+   .dirty = {
+      .mesa  = 0,
+      .st   = ST_NEW_VERTEX_PROGRAM,
+   },
+   .update = update_vs
+};
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
new file mode 100644 (file)
index 0000000..6da2aeb
--- /dev/null
@@ -0,0 +1,170 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "st_context.h"
+#include "st_program.h"    
+
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "program.h"
+#include "programopt.h"
+#include "tnl/tnl.h"
+#include "pipe/tgsi/mesa/tgsi_mesa.h"
+
+
+static void st_bind_program( GLcontext *ctx,
+                            GLenum target, 
+                            struct gl_program *prog )
+{
+   struct st_context *st = st_context(ctx);
+
+   switch (target) {
+   case GL_VERTEX_PROGRAM_ARB: 
+      st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
+      break;
+   case GL_FRAGMENT_PROGRAM_ARB:
+      st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+      break;
+   }
+}
+
+static struct gl_program *st_new_program( GLcontext *ctx,
+                                         GLenum target, 
+                                         GLuint id )
+{
+   struct st_context *st = st_context(ctx);
+
+   switch (target) {
+   case GL_VERTEX_PROGRAM_ARB: {
+      struct st_vertex_program *prog = CALLOC_STRUCT(st_vertex_program);
+
+      prog->id = st->program_id++;
+      prog->dirty = 1;
+
+      return _mesa_init_vertex_program( ctx, 
+                                       &prog->Base,
+                                       target, 
+                                       id );
+   }
+
+   case GL_FRAGMENT_PROGRAM_ARB:
+   case GL_FRAGMENT_PROGRAM_NV:
+   {
+      struct st_fragment_program *prog = CALLOC_STRUCT(st_fragment_program);
+
+      prog->id = st->program_id++;
+      prog->dirty = 1;
+
+      return _mesa_init_fragment_program( ctx, 
+                                         &prog->Base,
+                                         target, 
+                                         id );
+   }
+
+   default:
+      return _mesa_new_program(ctx, target, id);
+   }
+}
+
+static void st_delete_program( GLcontext *ctx,
+                              struct gl_program *prog )
+{
+   _mesa_delete_program( ctx, prog );
+}
+
+
+static GLboolean st_is_program_native( GLcontext *ctx,
+                                      GLenum target, 
+                                      struct gl_program *prog )
+{
+   return GL_TRUE;
+}
+
+static void st_program_string_notify( GLcontext *ctx,
+                                     GLenum target,
+                                     struct gl_program *prog )
+{
+   struct st_context *st = st_context(ctx);
+
+   if (target == GL_FRAGMENT_PROGRAM_ARB) {
+      struct st_fragment_program *p = (struct st_fragment_program *)prog;
+
+      if (prog == &ctx->FragmentProgram._Current->Base)
+        st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+
+      p->id = st->program_id++;      
+      p->param_state = p->Base.Base.Parameters->StateFlags;
+   }
+   else if (target == GL_VERTEX_PROGRAM_ARB) {
+      struct st_vertex_program *p = (struct st_vertex_program *)prog;
+
+      if (prog == &ctx->VertexProgram._Current->Base)
+        st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
+
+      p->id = st->program_id++;      
+      p->param_state = p->Base.Base.Parameters->StateFlags;
+
+      /* Also tell tnl about it:
+       */
+      _tnl_program_string(ctx, target, prog);
+   }
+}
+
+
+
+void st_init_cb_program( struct st_context *st )
+{
+   struct dd_function_table *functions = &st->ctx->Driver;
+
+   /* Need these flags:
+    */
+   st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
+   st->ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE;
+
+#if 0
+   assert(functions->ProgramStringNotify == _tnl_program_string); 
+#endif
+   functions->BindProgram = st_bind_program;
+   functions->NewProgram = st_new_program;
+   functions->DeleteProgram = st_delete_program;
+   functions->IsProgramNative = st_is_program_native;
+   functions->ProgramStringNotify = st_program_string_notify;
+}
+
+
+void st_destroy_cb_program( struct st_context *st )
+{
+}
+
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
new file mode 100644 (file)
index 0000000..6308e81
--- /dev/null
@@ -0,0 +1,76 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "imports.h"
+#include "st_public.h"
+#include "st_context.h"
+#include "st_atom.h"
+#include "st_draw.h"
+#include "st_program.h"
+#include "pipe/p_context.h"
+
+void st_invalidate_state(GLcontext * ctx, GLuint new_state)
+{
+   struct st_context *st = st_context(ctx);
+
+   st->dirty.mesa |= new_state;
+   st->dirty.st |= ST_NEW_MESA;
+}
+
+
+struct st_context *st_create_context( GLcontext *ctx,
+                                     struct pipe_context *pipe )
+{
+   struct st_context *st = CALLOC_STRUCT( st_context );
+   
+   ctx->st = st;
+
+   st->ctx = ctx;
+   st->pipe = pipe;
+
+   st->dirty.mesa = ~0;
+   st->dirty.st = ~0;
+
+   st_init_atoms( st );
+   st_init_draw( st );
+   st_init_cb_program( st );
+
+   return st;
+}
+
+
+void st_destroy_context( struct st_context *st )
+{
+   st_destroy_atoms( st );
+   st_destroy_draw( st );
+   st_destroy_cb_program( st );
+   st->pipe->destroy( st->pipe );
+   FREE( st );
+}
+
+
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
new file mode 100644 (file)
index 0000000..ef3cdb3
--- /dev/null
@@ -0,0 +1,116 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#ifndef ST_CONTEXT_H
+#define ST_CONTEXT_H
+
+#include "mtypes.h"
+#include "pipe/p_state.h"
+
+
+struct st_context;
+struct st_region;
+struct st_texture_object;
+struct st_texture_image;
+struct st_fragment_program;
+
+#define ST_NEW_MESA                    0x1 /* Mesa state has changed */
+#define ST_NEW_FRAGMENT_PROGRAM        0x2
+#define ST_NEW_VERTEX_PROGRAM          0x4
+
+struct st_state_flags {
+   GLuint mesa;
+   GLuint st;
+};
+
+struct st_tracked_state {
+   struct st_state_flags dirty;
+   void (*update)( struct st_context *st );
+};
+
+
+
+
+struct st_context
+{
+   GLcontext *ctx;
+
+   struct pipe_context *pipe;
+
+   /* Eventually will use a cache to feed the pipe with
+    * create/bind/delete calls to constant state objects.  Not yet
+    * though, we just shove random objects across the interface.  
+    */
+   struct {
+      struct pipe_alpha_test_state  alpha_test;
+      struct pipe_blend_state  blend;
+      struct pipe_blend_color  blend_color;
+      struct pipe_clear_color_state clear_color;
+      struct pipe_clip_state clip;
+      struct pipe_depth_state depth;
+      struct pipe_framebuffer_state framebuffer;
+      struct pipe_fs_state     fs;
+      struct pipe_poly_stipple poly_stipple;
+      struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
+      struct pipe_scissor_state scissor;
+      struct pipe_setup_state  setup;
+      struct pipe_stencil_state stencil;
+      struct pipe_viewport_state viewport;
+   } state;
+
+   struct {
+      struct st_tracked_state tracked_state;
+   } constants;
+
+   struct {
+      struct gl_fragment_program *fragment_program;
+   } cb;
+
+   /* State to be validated:
+    */
+   struct st_tracked_state **atoms;
+   GLuint nr_atoms;
+
+   struct st_state_flags dirty;
+
+   /* Counter to track program string changes:
+    */
+   GLuint program_id;
+
+   GLfloat polygon_offset_scale; /* ?? */
+};
+
+
+/* Need this so that we can implement Mesa callbacks in this module.
+ */
+static INLINE struct st_context *st_context(GLcontext *ctx)
+{
+   return ctx->st;
+}
+
+
+#endif
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
new file mode 100644 (file)
index 0000000..a424d1d
--- /dev/null
@@ -0,0 +1,120 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "imports.h"
+
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "st_draw.h"
+#include "pipe/p_context.h"
+
+/*
+ * TNL stage which feeds into the above.
+ *
+ * XXX: this needs to go into each driver using this code, because we
+ * cannot make the leap from ctx->draw_context in this file.  The
+ * driver needs to customize tnl anyway, so this isn't a big deal.
+ */
+static GLboolean draw( GLcontext * ctx, struct tnl_pipeline_stage *stage )
+{
+   struct st_context *st = st_context(ctx);
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+
+   /* Validate driver and pipe state:
+    */
+   st_validate_state( st );
+
+   /* Call into the new draw code to handle the VB:
+    */
+   st->pipe->draw_vb( st->pipe, VB );
+   
+   /* Finished 
+    */
+   return GL_FALSE;
+}
+
+const struct tnl_pipeline_stage st_draw = {
+   "check state and draw",
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   draw
+};
+
+static const struct tnl_pipeline_stage *st_pipeline[] = {
+   &_tnl_vertex_transform_stage,
+   &_tnl_vertex_cull_stage,
+   &_tnl_normal_transform_stage,
+   &_tnl_lighting_stage,
+   &_tnl_fog_coordinate_stage,
+   &_tnl_texgen_stage,
+   &_tnl_texture_transform_stage,
+   &_tnl_point_attenuation_stage,
+   &_tnl_vertex_program_stage,
+   &st_draw,     /* ADD: escape to pipe */
+   0,
+};
+
+/* This is all a hack to keep using tnl until we have vertex programs
+ * up and running.
+ */
+void st_init_draw( struct st_context *st )
+{
+   GLcontext *ctx = st->ctx;
+
+   _tnl_destroy_pipeline( ctx );
+   _tnl_install_pipeline( ctx, st_pipeline );
+}
+
+
+void st_destroy_draw( struct st_context *st )
+{
+   /* Nothing to do. 
+    */
+}
+
+
+/** XXX temporary here */
+void
+st_clear(struct st_context *st, GLboolean color, GLboolean depth,
+         GLboolean stencil, GLboolean accum)
+{
+   /* This makes sure the softpipe has the latest scissor, etc values */
+   st_validate_state( st );
+
+   st->pipe->clear(st->pipe, color, depth, stencil, accum);
+}
+
diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h
new file mode 100644 (file)
index 0000000..7a3ba52
--- /dev/null
@@ -0,0 +1,44 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+    
+
+#ifndef ST_DRAW_H
+#define ST_DRAW_H
+
+void st_init_draw( struct st_context *st );
+void st_destroy_draw( struct st_context *st );
+
+/** XXX temporary here */
+void st_clear(struct st_context *st, GLboolean color, GLboolean depth,
+              GLboolean stencil, GLboolean accum);
+
+#endif
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
new file mode 100644 (file)
index 0000000..f6d5f6d
--- /dev/null
@@ -0,0 +1,105 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+    
+
+#ifndef ST_PROGRAM_H
+#define ST_PROGRAM_H
+
+#include "mtypes.h"
+#include "pipe/tgsi/core/tgsi_token.h"
+
+#define ST_FP_MAX_TOKENS 1024
+
+
+struct st_fragment_program
+{
+   struct gl_fragment_program Base;
+   GLboolean error;             /* If program is malformed for any reason. */
+
+   GLuint    id;               /* String id, for tracking
+                                * ProgramStringNotify changes.
+                                */
+
+
+   struct tgsi_token tokens[ST_FP_MAX_TOKENS];
+   GLboolean dirty;
+   
+   struct pipe_constant_buffer constants;
+
+#if 0   
+   GLfloat (*cbuffer)[4];
+   GLuint nr_constants;
+
+   /* Translate all the parameters, etc, into a constant buffer which
+    * we update on state changes.
+    */
+   struct
+   {
+      GLuint reg;               /* Constant idx */
+      const GLfloat *values;    /* Pointer to tracked values */
+   } *param;
+   GLuint nr_params;
+#endif
+
+   GLuint param_state;
+};
+
+
+struct st_vertex_program
+{
+   struct gl_vertex_program Base;
+   GLboolean error;             /* If program is malformed for any reason. */
+
+   GLuint    id;               /* String id, for tracking
+                                * ProgramStringNotify changes.
+                                */
+
+   GLboolean dirty;
+   GLuint param_state;
+};
+
+void st_init_cb_program( struct st_context *st );
+void st_destroy_cb_program( struct st_context *st );
+
+static inline struct st_fragment_program *
+st_fragment_program( struct gl_fragment_program *fp )
+{
+   return (struct st_fragment_program *)fp;
+}
+
+static inline struct st_vertex_program *
+st_vertex_program( struct gl_vertex_program *vp )
+{
+   return (struct st_vertex_program *)vp;
+}
+
+#endif
diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h
new file mode 100644 (file)
index 0000000..3191549
--- /dev/null
@@ -0,0 +1,43 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#ifndef ST_PUBLIC_H
+#define ST_PUBLIC_H
+
+#include "mtypes.h"
+
+struct st_context;
+struct pipe_context;
+
+struct st_context *st_create_context( GLcontext *ctx,
+                                     struct pipe_context *pipe);
+
+void st_destroy_context( struct st_context *st );
+
+void st_invalidate_state(GLcontext * ctx, GLuint new_state);
+
+#endif
diff --git a/src/mesa/state_tracker/st_texobj.c b/src/mesa/state_tracker/st_texobj.c
new file mode 100644 (file)
index 0000000..eb5bdb2
--- /dev/null
@@ -0,0 +1,102 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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:
+ *   Brian Paul
+ */
+
+#include "imports.h"
+#include "texformat.h"
+
+#include "st_context.h"
+#include "st_texobj.h"
+#include "pipe/p_defines.h"
+
+
+/**
+ * Create a pipe_texture_object from a Mesa texture object.
+ * Eventually, gl_texture_object may be derived from this...
+ */
+struct pipe_texture_object *
+create_texture_object(struct gl_texture_object *texObj)
+{
+   struct pipe_texture_object *pto;
+   const struct gl_texture_image *texImage;
+
+   pto = calloc(1, sizeof(*pto));
+   if (!pto)
+      return NULL;
+
+   /* XXX: Member not defined. Comment-out to get it compile. */
+   /*assert(texObj->Complete);*/
+
+   switch (texObj->Target) {
+   case GL_TEXTURE_1D:
+      pto->type = PIPE_TEXTURE_1D;
+      break;
+   case GL_TEXTURE_2D:
+      pto->type = PIPE_TEXTURE_2D;
+      break;
+   case GL_TEXTURE_3D:
+      pto->type = PIPE_TEXTURE_3D;
+      break;
+   case GL_TEXTURE_CUBE_MAP:
+      pto->type = PIPE_TEXTURE_CUBE;
+      break;
+   default:
+      assert(0);
+      return NULL;
+   }
+
+   texImage = texObj->Image[0][texObj->BaseLevel];
+   assert(texImage);
+
+   switch (texImage->TexFormat->MesaFormat) {
+   case MESA_FORMAT_RGBA8888:
+      pto->format = PIPE_FORMAT_U_R8_G8_B8_A8;
+      break;
+   case MESA_FORMAT_RGB565:
+      pto->format = PIPE_FORMAT_U_R5_G6_B5;
+      break;
+
+   /* XXX fill in more formats */
+
+   default:
+      assert(0);
+      return NULL;
+   }
+
+   pto->width = texImage->Width;
+   pto->height = texImage->Height;
+   pto->depth = texImage->Depth;
+
+   /* XXX verify this */
+   pto->mipmapped = texObj->Image[0][texObj->BaseLevel + 1] != NULL;
+
+   return pto;
+}
diff --git a/src/mesa/state_tracker/st_texobj.h b/src/mesa/state_tracker/st_texobj.h
new file mode 100644 (file)
index 0000000..3c66031
--- /dev/null
@@ -0,0 +1,41 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 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:
+ *   Brian Paul
+ */
+
+#ifndef ST_TEXOBJ_H
+#define ST_TEXOBJ_H 1
+
+
+extern struct pipe_texture_object *
+create_texture_object(struct gl_texture_object *texObj);
+
+
+#endif /* ST_TEXOBJ_H */
index 69a1f0cd3961fad98816734c68324abc46b2adce..e7911fec3b5536bf98cdb539bff0cdf4aa1a583b 100644 (file)
@@ -132,7 +132,9 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
    line.dx = line.x1 - line.x0;
    line.dy = line.y1 - line.y0;
    line.len = SQRTF(line.dx * line.dx + line.dy * line.dy);
-   line.halfWidth = 0.5F * ctx->Line._Width;
+   line.halfWidth = 0.5F * CLAMP(ctx->Line.Width,
+                                 ctx->Const.MinLineWidthAA,
+                                 ctx->Const.MaxLineWidthAA);
 
    if (line.len == 0.0 || IS_INF_OR_NAN(line.len))
       return;
index 947054faa3053fca17463af6a37e6cc2bd6b72db..55ec757ee069b67f8aa1ce1c999da90e819709cb 100644 (file)
 #include "glheader.h"
 #include "colormac.h"
 #include "context.h"
-#include "atifragshader.h"
 #include "macros.h"
-#include "program.h"
-
-#include "s_atifragshader.h"
+#include "shader/program.h"
+#include "shader/atifragshader.h"
+#include "swrast/s_atifragshader.h"
 
 
 /**
index 791850cb5028fa7c55d2917f96473a23796e6149..395692565148856f0ea49dbb429c95862509e8ef 100644 (file)
@@ -31,9 +31,9 @@
 #include "context.h"
 #include "colormac.h"
 #include "mtypes.h"
-#include "prog_statevars.h"
 #include "teximage.h"
 #include "swrast.h"
+#include "shader/prog_statevars.h"
 #include "s_blend.h"
 #include "s_context.h"
 #include "s_lines.h"
index f118eb92ca463718164f07283686c7ec1241a4bf..daa07e15783af7dfd0cd555c8d7390c65d8cf122 100644 (file)
 #ifndef S_CONTEXT_H
 #define S_CONTEXT_H
 
-#include "mtypes.h"
+#include "main/mtypes.h"
+#include "shader/prog_execute.h"
 #include "swrast.h"
 #include "s_span.h"
-#include "prog_execute.h"
 
 
 typedef void (*texture_sample_func)(GLcontext *ctx,
index 1c9f64b275e755669720c893872b88929c2ebb4d..0cf425e1c62a588e270b4cdede692661678512ef 100644 (file)
@@ -484,7 +484,7 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
    }
    else {
       /* General case */
-      const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
+      const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
       GLint skipPixels = 0;
 
       /* in case width > MAX_WIDTH do the copy in chunks */
@@ -695,7 +695,7 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
    const GLint imgX = x, imgY = y;
    const GLboolean scaleOrBias
       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
-   const GLfloat depthScale = ctx->DrawBuffer->_DepthMaxF;
+   const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
    const GLuint stencilMask = ctx->Stencil.WriteMask[0];
    const GLuint stencilType = (STENCIL_BITS == 8) ? 
       GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
@@ -783,7 +783,7 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
                /* general case */
                GLuint zValues[MAX_WIDTH];  /* 16 or 32-bit Z value storage */
                _mesa_unpack_depth_span(ctx, width,
-                                       depthRb->DataType, zValues, depthScale,
+                                       depthRb->DataType, zValues, depthMax,
                                        type, depthStencilSrc, &clippedUnpack);
                if (zoom) {
                   _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x,
index 923b67e78e6c44102826c1a89475b3574f127f43..14c9868c1803ba4adfef8acc5757d56438614e30 100644 (file)
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "glheader.h"
-#include "colormac.h"
-#include "context.h"
-#include "prog_instruction.h"
-#include "texstate.h"
+#include "main/glheader.h"
+#include "main/colormac.h"
+#include "main/context.h"
+#include "main/texstate.h"
+#include "shader/prog_instruction.h"
 
 #include "s_fragprog.h"
 #include "s_span.h"
index 781146e67f93ff4d00be86e38891781f186f4910..3de438760b52cf9f5fb36a404fbee353e77231d1 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.1
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -63,12 +63,13 @@ compute_stipple_mask( GLcontext *ctx, GLuint len, GLubyte mask[] )
 static void
 draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
 {
-   GLint width, start;
+   const GLint width = (GLint) CLAMP(ctx->Line.Width,
+                                     ctx->Const.MinLineWidth,
+                                     ctx->Const.MaxLineWidth);
+   GLint start;
 
    ASSERT(span->end < MAX_WIDTH);
 
-   width = (GLint) CLAMP( ctx->Line._Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
-
    if (width & 1)
       start = width / 2;
    else
@@ -143,7 +144,7 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
       span.arrayMask |= SPAN_MASK;                             \
       compute_stipple_mask(ctx, span.end, span.array->mask);    \
    }                                                           \
-   if (ctx->Line._Width > 1.0) {                               \
+   if (ctx->Line.Width > 1.0) {                                        \
       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));                \
    }                                                           \
    else {                                                      \
@@ -161,7 +162,7 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
       span.arrayMask |= SPAN_MASK;                             \
       compute_stipple_mask(ctx, span.end, span.array->mask);   \
    }                                                           \
-   if (ctx->Line._Width > 1.0) {                               \
+   if (ctx->Line.Width > 1.0) {                                        \
       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));                \
    }                                                           \
    else {                                                      \
@@ -180,7 +181,7 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
       span.arrayMask |= SPAN_MASK;                             \
       compute_stipple_mask(ctx, span.end, span.array->mask);   \
    }                                                           \
-   if (ctx->Line._Width > 1.0) {                               \
+   if (ctx->Line.Width > 1.0) {                                        \
       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));                \
    }                                                           \
    else {                                                      \
@@ -274,16 +275,21 @@ _swrast_choose_line( GLcontext *ctx )
          USE(general_line);
       }
       else if (ctx->Depth.Test
-               || ctx->Line._Width != 1.0
+               || ctx->Line.Width != 1.0
                || ctx->Line.StippleFlag) {
          /* no texture, but Z, fog, width>1, stipple, etc. */
          if (rgbmode)
+#if CHAN_BITS == 32
+            USE(general_line);
+#else
             USE(rgba_line);
+#endif
          else
             USE(ci_line);
       }
       else {
          ASSERT(!ctx->Depth.Test);
+         ASSERT(ctx->Line.Width == 1.0);
          /* simple lines */
          if (rgbmode)
             USE(simple_no_z_rgba_line);
index 8eba53c80766ce64150402b3c62acdbedfae0ea3..4768fbea972bb5a3973f3a9fce026ff3ba0ac246 100644 (file)
@@ -76,7 +76,7 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
    }
    else {
       /* use constant point size */
-      size = ctx->Point._Size; /* already clamped to user range */
+      size = ctx->Point.Size;
    }
    /* clamp to non-AA implementation limits */
    size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
@@ -227,7 +227,7 @@ smooth_point(GLcontext *ctx, const SWvertex *vert)
    }
    else {
       /* use constant point size */
-      size = ctx->Point._Size; /* this is already clamped */
+      size = ctx->Point.Size;
    }
    /* clamp to AA implementation limits */
    size = CLAMP(size, ctx->Const.MinPointSizeAA, ctx->Const.MaxPointSizeAA);
@@ -361,7 +361,7 @@ large_point(GLcontext *ctx, const SWvertex *vert)
    }
    else {
       /* use constant point size */
-      size = ctx->Point._Size; /* already clamped to user range */
+      size = ctx->Point.Size;
    }
    /* clamp to non-AA implementation limits */
    size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
@@ -550,7 +550,7 @@ _swrast_choose_point(GLcontext *ctx)
       else if (ctx->Point.SmoothFlag) {
          swrast->Point = smooth_point;
       }
-      else if (ctx->Point._Size > 1.0 ||
+      else if (ctx->Point.Size > 1.0 ||
                ctx->Point._Attenuated ||
                ctx->VertexProgram.PointSizeEnabled) {
          swrast->Point = large_point;
index f23272c2beec5271433972883341f1ee0a1382c2..cfc65bee87fe101310a3e3298c8e8cd161f0aaaf 100644 (file)
@@ -1358,7 +1358,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
 
 #if CHAN_BITS == 32
    if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
-      interpolate_int_colors(ctx, span);
+      interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
    }
 #else
    if ((span->arrayMask & SPAN_RGBA) == 0) {
index 89991fad02d6a4d605d922efecc729fa121a5ddf..d0cbdd6917d837bf3b1c0ff88f123f0a1b4ec1a9 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  7.1
  *
- * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -392,6 +392,23 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
 }
 
 
+/**
+ * Compute the zpass/zfail masks by comparing the pre- and post-depth test
+ * masks.
+ */
+static INLINE void
+compute_pass_fail_masks(GLuint n, const GLubyte origMask[],
+                        const GLubyte newMask[],
+                        GLubyte passMask[], GLubyte failMask[])
+{
+   GLuint i;
+   for (i = 0; i < n; i++) {
+      ASSERT(newMask[i] == 0 || newMask[i] == 1);
+      passMask[i] = origMask[i] & newMask[i];
+      failMask[i] = origMask[i] & (newMask[i] ^ 1);
+   }
+}
+
 
 /**
  * Apply stencil and depth testing to the span of pixels.
@@ -460,39 +477,24 @@ stencil_and_ztest_span(GLcontext *ctx, SWspan *span, GLuint face)
       /*
        * Perform depth buffering, then apply zpass or zfail stencil function.
        */
-      GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH];
-      GLuint i;
+      GLubyte passMask[MAX_WIDTH], failMask[MAX_WIDTH], origMask[MAX_WIDTH];
 
       /* save the current mask bits */
-      _mesa_memcpy(oldmask, mask, n * sizeof(GLubyte));
+      _mesa_memcpy(origMask, mask, n * sizeof(GLubyte));
 
       /* apply the depth test */
       _swrast_depth_test_span(ctx, span);
 
-      /* Set the stencil pass/fail flags according to result of depth testing.
-       * if oldmask[i] == 0 then
-       *    Don't touch the stencil value
-       * else if oldmask[i] and newmask[i] then
-       *    Depth test passed
-       * else
-       *    assert(oldmask[i] && !newmask[i])
-       *    Depth test failed
-       * endif
-       */
-      for (i=0;i<n;i++) {
-         ASSERT(mask[i] == 0 || mask[i] == 1);
-         passmask[i] = oldmask[i] & mask[i];
-         failmask[i] = oldmask[i] & (mask[i] ^ 1);
-      }
+      compute_pass_fail_masks(n, origMask, mask, passMask, failMask);
 
       /* apply the pass and fail operations */
       if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
          apply_stencil_op( ctx, ctx->Stencil.ZFailFunc[face], face,
-                           n, stencil, failmask );
+                           n, stencil, failMask );
       }
       if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
          apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face,
-                           n, stencil, passmask );
+                           n, stencil, passMask );
       }
    }
 
@@ -902,6 +904,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n,
 static GLboolean
 stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face )
 {
+   GLubyte passMask[MAX_WIDTH], failMask[MAX_WIDTH], origMask[MAX_WIDTH];
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    struct gl_renderbuffer *rb = fb->_StencilBuffer;
    const GLuint n = span->end;
@@ -916,13 +919,10 @@ stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face )
    if (!rb->GetPointer(ctx, rb, 0, 0)) {
       /* No direct access */
       GLstencil stencil[MAX_WIDTH];
-      GLubyte origMask[MAX_WIDTH];
 
       ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
       _swrast_get_values(ctx, rb, n, x, y, stencil, sizeof(GLubyte));
 
-      _mesa_memcpy(origMask, mask, n * sizeof(GLubyte));
-
       (void) do_stencil_test(ctx, face, n, stencil, mask);
 
       if (ctx->Depth.Test == GL_FALSE) {
@@ -930,27 +930,19 @@ stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face )
                           n, stencil, mask);
       }
       else {
+         _mesa_memcpy(origMask, mask, n * sizeof(GLubyte));
+
          _swrast_depth_test_span(ctx, span);
 
+         compute_pass_fail_masks(n, origMask, mask, passMask, failMask);
+
          if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
-            GLubyte failmask[MAX_WIDTH];
-            GLuint i;
-            for (i = 0; i < n; i++) {
-               ASSERT(mask[i] == 0 || mask[i] == 1);
-               failmask[i] = origMask[i] & (mask[i] ^ 1);
-            }
             apply_stencil_op(ctx, ctx->Stencil.ZFailFunc[face], face,
-                             n, stencil, failmask);
+                             n, stencil, failMask);
          }
          if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
-            GLubyte passmask[MAX_WIDTH];
-            GLuint i;
-            for (i = 0; i < n; i++) {
-               ASSERT(mask[i] == 0 || mask[i] == 1);
-               passmask[i] = origMask[i] & mask[i];
-            }
             apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face,
-                             n, stencil, passmask);
+                             n, stencil, passMask);
          }
       }
 
@@ -972,28 +964,21 @@ stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face )
                                     ctx->Stencil.ZPassFunc[face], face, mask);
       }
       else {
-         GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH];
-         GLuint i;
-
-         _mesa_memcpy(oldmask, mask, n * sizeof(GLubyte));
+         _mesa_memcpy(origMask, mask, n * sizeof(GLubyte));
 
          _swrast_depth_test_span(ctx, span);
 
-         for (i=0;i<n;i++) {
-            ASSERT(mask[i] == 0 || mask[i] == 1);
-            passmask[i] = oldmask[i] & mask[i];
-            failmask[i] = oldmask[i] & (mask[i] ^ 1);
-         }
+         compute_pass_fail_masks(n, origMask, mask, passMask, failMask);
 
          if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
             apply_stencil_op_to_pixels(ctx, n, x, y,
                                        ctx->Stencil.ZFailFunc[face],
-                                       face, failmask);
+                                       face, failMask);
          }
          if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
             apply_stencil_op_to_pixels(ctx, n, x, y,
                                        ctx->Stencil.ZPassFunc[face],
-                                       face, passmask);
+                                       face, passMask);
          }
       }
 
index d101a9e2ae256deb305b95dab0bee2a5fffd63ca..85a27fd55bf534cdce0011fa63f525cf7c4fcf6d 100644 (file)
@@ -32,7 +32,7 @@
 #ifndef SWRAST_H
 #define SWRAST_H
 
-#include "mtypes.h"
+#include "main/mtypes.h"
 
 /**
  * \struct SWvertex
index f8a1cadfa5a01e5af9fb961c7dfccd6267272a69..a9c7d941e5b17e09d6b95a449025ffaf8df00646 100644 (file)
@@ -280,26 +280,29 @@ _swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest )
 
    /** XXX try to limit these loops someday */
    for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
-      _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0+i,
+      _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0 + i,
                      dest->attrib[FRAG_ATTRIB_TEX0 + i] );
 
    for (i = 0 ; i < ctx->Const.MaxVarying ; i++)
-      _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_GENERIC0+i,
+      _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_GENERIC0 + i,
                      dest->attrib[FRAG_ATTRIB_VAR0 + i] );
 
-   _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR0, tmp );
-   /* XXX need float color FRAG_ATTRIB_COL0?? */
-   UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp );
+   if (ctx->Visual.rgbMode) {
+      _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR0,
+                     dest->attrib[FRAG_ATTRIB_COL0] );
+      UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp );
 
-   _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR1, tmp );
-   COPY_4V(dest->attrib[FRAG_ATTRIB_COL1], tmp);
+      _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR1,
+                     dest->attrib[FRAG_ATTRIB_COL1]);
+   }
+   else {
+      _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR_INDEX, tmp );
+      dest->attrib[FRAG_ATTRIB_CI][0] = tmp[0];
+   }
 
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_FOG, tmp );
    dest->attrib[FRAG_ATTRIB_FOGC][0] = tmp[0];
 
-   _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR_INDEX, tmp );
-   dest->attrib[FRAG_ATTRIB_CI][0] = tmp[0];
-
    /* XXX See _tnl_get_attr about pointsize ... */
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POINTSIZE, tmp );
    dest->pointSize = tmp[0];
index c14468e9514be5f213b461c53d895f43988630b2..f6b738d60dfc2d3ffb383faaf65ddb885c059cc6 100644 (file)
@@ -37,7 +37,7 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
    SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts;
    SWvertex *v[3];
    GLfloat z[3];
-   GLfloat offset;
+   GLfloat offset, oz0, oz1, oz2;
    GLenum mode = GL_FILL;
    GLuint facing = 0;
    GLchan saved_color[3][4];
@@ -142,12 +142,16 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
         }
       }
 
-      if (IND & SS_OFFSET_BIT)
-      {
-        offset = ctx->Polygon.OffsetUnits * ctx->DrawBuffer->_MRD;
+      if (IND & SS_OFFSET_BIT) {
+         const GLfloat max = ctx->DrawBuffer->_DepthMaxF;
+         /* save original Z values (restored later) */
         z[0] = v[0]->attrib[FRAG_ATTRIB_WPOS][2];
         z[1] = v[1]->attrib[FRAG_ATTRIB_WPOS][2];
         z[2] = v[2]->attrib[FRAG_ATTRIB_WPOS][2];
+         /* Note that Z values are already scaled to [0,65535] (for example)
+          * so no MRD value is used here.
+          */
+        offset = ctx->Polygon.OffsetUnits;
         if (cc * cc > 1e-16) {
            const GLfloat ez = z[0] - z[2];
            const GLfloat fz = z[1] - z[2];
@@ -155,35 +159,33 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
            const GLfloat dzdx = FABSF((ey * fz - ez * fy) * oneOverArea);
            const GLfloat dzdy = FABSF((ez * fx - ex * fz) * oneOverArea);
            offset += MAX2(dzdx, dzdy) * ctx->Polygon.OffsetFactor;
-            /* Unfortunately, we need to clamp to prevent negative Zs below.
-             * Technically, we should do the clamping per-fragment.
-             */
-            offset = MAX2(offset, -v[0]->attrib[FRAG_ATTRIB_WPOS][2]);
-            offset = MAX2(offset, -v[1]->attrib[FRAG_ATTRIB_WPOS][2]);
-            offset = MAX2(offset, -v[2]->attrib[FRAG_ATTRIB_WPOS][2]);
         }
+         /* new Z values */
+         oz0 = CLAMP(v[0]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0, max);
+         oz1 = CLAMP(v[1]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0, max);
+         oz2 = CLAMP(v[2]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0, max);
       }
    }
 
    if (mode == GL_POINT) {
       if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) {
-        v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
-        v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
-        v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+        v[0]->attrib[FRAG_ATTRIB_WPOS][2] = oz0;
+        v[1]->attrib[FRAG_ATTRIB_WPOS][2] = oz1;
+        v[2]->attrib[FRAG_ATTRIB_WPOS][2] = oz2;
       }
       _swsetup_render_point_tri( ctx, e0, e1, e2, facing );
    } else if (mode == GL_LINE) {
       if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) {
-        v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
-        v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
-        v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+        v[0]->attrib[FRAG_ATTRIB_WPOS][2] = oz0;
+        v[1]->attrib[FRAG_ATTRIB_WPOS][2] = oz1;
+        v[2]->attrib[FRAG_ATTRIB_WPOS][2] = oz2;
       }
       _swsetup_render_line_tri( ctx, e0, e1, e2, facing );
    } else {
       if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) {
-        v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
-        v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
-        v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+        v[0]->attrib[FRAG_ATTRIB_WPOS][2] = oz0;
+        v[1]->attrib[FRAG_ATTRIB_WPOS][2] = oz1;
+        v[2]->attrib[FRAG_ATTRIB_WPOS][2] = oz2;
       }
       _swrast_Triangle( ctx, v[0], v[1], v[2] );
    }
index 3017c73cf1f828beb9229697e306921fbc44dc85..3b8dd18bbb2bb53a9e6cbb7d039fd510a1cacb71 100644 (file)
  */
 
 
-#include "glheader.h"
-#include "imports.h"
-#include "context.h"
-#include "macros.h"
-#include "mtypes.h"
-#include "light.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/light.h"
 
 #include "tnl.h"
 #include "t_context.h"
index 31b89aca41f2bc344e0f23c4fbbd2a7179cf727c..baf283ef0f61fbd1e865c8c74015d1690bae3300 100644 (file)
@@ -49,8 +49,8 @@
 #ifndef _T_CONTEXT_H
 #define _T_CONTEXT_H
 
-#include "glheader.h"
-#include "mtypes.h"
+#include "main/glheader.h"
+#include "main/mtypes.h"
 
 #include "math/m_matrix.h"
 #include "math/m_vector.h"
index c7188da34aaaa25a39f1aed7d1a5f548fc219009..2a0ed8852a2b027ba986da59cc85b199622d1308 100644 (file)
  *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "glheader.h"
-#include "context.h"
-#include "imports.h"
-#include "state.h"
-#include "mtypes.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/imports.h"
+#include "main/state.h"
+#include "main/mtypes.h"
 
 #include "t_context.h"
 #include "t_pipeline.h"
index 9961af70ce7e1ce534e956b0af4fed6a141f7aae..f8e561ac57e3389e5307364de469949ca9697a20 100644 (file)
 #include "context.h"
 #include "macros.h"
 #include "imports.h"
-#include "prog_instruction.h"
-#include "prog_statevars.h"
-#include "prog_execute.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_statevars.h"
+#include "shader/prog_execute.h"
+#include "swrast/s_context.h"
+#include "swrast/s_texfilter.h"
 
 #include "tnl.h"
 #include "t_context.h"
 #include "t_pipeline.h"
 
-#include "swrast/s_context.h"
-#include "swrast/s_texfilter.h"
 
 /**
  * XXX the texture sampling code in this module is a bit of a hack.
index 6aae602037576f2468cf05ebea35d4c1cdbb7524..a6728c318fe3171be817885335216c0fc87a8d5b 100644 (file)
@@ -233,7 +233,7 @@ void _tnl_get_attr( GLcontext *ctx, const void *vin,
       /* If the hardware vertex doesn't have point size then use size from
        * GLcontext.  XXX this will be wrong if drawing attenuated points!
        */
-      dest[0] = ctx->Point._Size;
+      dest[0] = ctx->Point.Size;
    }
    else {
       _mesa_memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat));
index 2a1cae77f29feda7c9379d358158d1e1d865dfde..ee1a2498b320e400057040d19aebb79e7724e16a 100644 (file)
 #include "glheader.h"
 #include "macros.h"
 #include "enums.h"
-#include "program.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "prog_statevars.h"
+#include "shader/program.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
+#include "shader/prog_statevars.h"
 #include "t_context.h" /* NOTE: very light dependency on this */
 #include "t_vp_build.h"
 
index 20bed5546de575a227988434f55a4cec335928e4..047b764dcba88602047b63a69abfb2874b57e2df 100644 (file)
@@ -29,7 +29,7 @@
 #ifndef _TNL_H
 #define _TNL_H
 
-#include "mtypes.h"
+#include "main/mtypes.h"
 
 
 
index ab3bb37631b42a5cfae8a82a8b91d89492657b56..3cedd9011904f99d6a21d2d4545c21034bc91b61 100644 (file)
@@ -184,7 +184,7 @@ void TAG(translate_vertex)(GLcontext *ctx,
       }
    }
 
-   dst->pointSize = ctx->Point._Size;
+   dst->pointSize = ctx->Point.Size;
 }
 
 
index 874a5f9e0e26a853751fb218b1a496d2262d08a2..04c59c05b277027281d91b4bcae52d39627b4250 100644 (file)
@@ -32,7 +32,7 @@
 #ifndef _VBO_H
 #define _VBO_H
 
-#include "mtypes.h"
+#include "main/mtypes.h"
 
 struct _mesa_prim {
    GLuint mode:8;
index f64f59d11ec17ebe400c2a2f5e39b98ffb75f953..ad4556c500b1274a022c5fb48b7cfe7dc0862c6a 100644 (file)
  *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "mtypes.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "main/api_arrayelt.h"
 #include "vbo.h"
 #include "vbo_context.h"
-#include "imports.h"
-#include "api_arrayelt.h"
 
 /* Reach out and grab this to use as the default:
  */
index 7d958732479f90c1c618208b94bca5e3a7f2e03a..1efa74945dd73afd9f5bcc8072cfd83773fb6c51 100644 (file)
  */
 
 
-#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 "main/api_arrayelt.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/dlist.h"
+#include "main/vtxfmt.h"
 
 #include "vbo_context.h"
 
index a9b01e08e6aa26a92d31691af100ce004eb1efb1..b7e8c9fe79f3bc8ee70fd5b3ddcc067705588485 100644 (file)
@@ -34,7 +34,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #ifndef __VBO_EXEC_H__
 #define __VBO_EXEC_H__
 
-#include "mtypes.h"
+#include "main/mtypes.h"
 #include "vbo.h"
 #include "vbo_attrib.h"
 
index 2d4ded0f984a2601bf5530e12921a15944d66ba6..7f56b3b62930d50be10ac8b2a053650dc590c3f2 100644 (file)
@@ -30,16 +30,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  *   Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "glheader.h"
-#include "context.h"
-#include "macros.h"
-#include "vtxfmt.h"
-#include "dlist.h"
-#include "state.h"
-#include "light.h"
-#include "api_arrayelt.h"
-#include "api_noop.h"
-#include "dispatch.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/vtxfmt.h"
+#include "main/dlist.h"
+#include "main/state.h"
+#include "main/light.h"
+#include "main/api_arrayelt.h"
+#include "main/api_noop.h"
+#include "glapi/dispatch.h"
 
 #include "vbo_context.h"
 
index 1e4c310203beec335762ae9412326c16c5e8c6cc..77f3cf1455bc04a46f2c7d755cc1156ca85aada1 100644 (file)
  * 
  **************************************************************************/
 
-#include "glheader.h"
-#include "context.h"
-#include "state.h"
-#include "api_validate.h"
-#include "api_noop.h"
-#include "dispatch.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/state.h"
+#include "main/api_validate.h"
+#include "main/api_noop.h"
+#include "glapi/dispatch.h"
 
 #include "vbo_context.h"
 
index d8f167b3577c7a0381a1ea6c9527b4d5054ca3b7..0ef26cdfe3676fad824faf4ca997e10188c086b0 100644 (file)
  *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "glheader.h"
-#include "context.h"
-#include "enums.h"
-#include "state.h"
-#include "macros.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/enums.h"
+#include "main/state.h"
+#include "main/macros.h"
 
 #include "vbo_context.h"
 
index fe533290bd18605f1072d1b0a20513b91e1d955c..0ba5585d246a9321debfb574fc50836bfe04b77e 100644 (file)
  *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "glheader.h"
-#include "api_eval.h"
-#include "context.h"
-#include "macros.h"
+#include "main/glheader.h"
+#include "main/api_eval.h"
+#include "main/context.h"
+#include "main/macros.h"
 #include "math/m_eval.h"
+#include "glapi/dispatch.h"
 #include "vbo_exec.h"
-#include "dispatch.h"
 
 
 static void clear_active_eval1( struct vbo_exec_context *exec, GLuint attr ) 
index bc4211d8529f18e773d07ee40e25cb69ea38bcd9..dae778e741ee02f91fba9f42eab0eb28cf8489e6 100644 (file)
@@ -46,9 +46,9 @@
  * of zero.
  */
 
-#include "glheader.h"
-#include "imports.h"
-#include "mtypes.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
 
 #include "vbo.h"
 
index e7f46879639c4eea88c92ca07dfb4d14212836b4..87248e10f3bc30e8b5e8ec89cbefef38bf797052 100644 (file)
  */
 
 
-#include "mtypes.h"
-#include "dlist.h"
-#include "vtxfmt.h"
-#include "imports.h"
+#include "main/mtypes.h"
+#include "main/dlist.h"
+#include "main/vtxfmt.h"
+#include "main/imports.h"
 
 #include "vbo_context.h"
 
index b81f275a6029ddcb606dd50b85c67a2f6b03b675..b7e9baabf8100e8f4a22d79deaea8a3c573051f1 100644 (file)
@@ -34,7 +34,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #ifndef VBO_SAVE_H
 #define VBO_SAVE_H
 
-#include "mtypes.h"
+#include "main/mtypes.h"
 #include "vbo.h"
 #include "vbo_attrib.h"
 
index e7794c2a6ccaaf257e244eeef0363fd0eb4dda91..aded73814361e462aac8897bd68b2bf6fde48f71 100644 (file)
@@ -67,15 +67,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
 
-#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 "main/glheader.h"
+#include "main/context.h"
+#include "main/dlist.h"
+#include "main/enums.h"
+#include "main/macros.h"
+#include "main/api_validate.h"
+#include "main/api_arrayelt.h"
+#include "main/vtxfmt.h"
+#include "glapi/dispatch.h"
 
 #include "vbo_context.h"
 
index 8940551d08b1ca416a5bfeccc2a92d197a48c540..3c6f0fccd98e41c51d311f37537f65e75e1c29fe 100644 (file)
  *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "glheader.h"
-#include "context.h"
-#include "imports.h"
-#include "mtypes.h"
-#include "macros.h"
-#include "light.h"
-#include "state.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "main/light.h"
+#include "main/state.h"
 
 #include "vbo_context.h"
 
index 430333b84dd002bfe88558df486882627bfd0f43..f2cef698fbedaab9938cfde6f0109b2029960f53 100644 (file)
 #include "swrast_setup/swrast_setup.h"
 #include "swrast/swrast.h"
 #include "tnl/tnl.h"
-#include "context.h"
+#include "main/context.h"
+#include "main/glheader.h"
+#include "main/enums.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "glapi/dispatch.h"
+#include "glapi/glapi.h"
 
 #include "vbo_context.h"
 
-#include "glheader.h"
-#include "enums.h"
-#include "glapi.h"
-#include "imports.h"
-#include "macros.h"
-#include "mtypes.h"
-#include "dispatch.h"
 
 
 typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * );
index ef205a3bb1fb47532131c6cc638eb2cc4a81f697..58e879628dea28cc2a594bae6e28fc78222258ff 100644 (file)
@@ -47,9 +47,9 @@
  * limitations on drivers which want to use it as a fallback path.
  */
 
-#include "glheader.h"
-#include "imports.h"
-#include "mtypes.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
 
 #include "vbo_split.h"
 #include "vbo.h"
index e142dde6803762c6cb85999505c31ef207e6fdfd..e5c4429350e49e99a33df34c7ad8f84b5db8ed97 100644 (file)
 /* Split indexed primitives with per-vertex copying.
  */
 
-#include "glheader.h"
-#include "imports.h"
-#include "macros.h"
-#include "enums.h"
-#include "mtypes.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/enums.h"
+#include "main/mtypes.h"
 
 #include "vbo_split.h"
 #include "vbo.h"
index ea62866e7c93fee5f66f713b2a2bf55861ec0a45..958afccd0c0a278e2c30a5288a6cc2a5f64e89a0 100644 (file)
@@ -27,9 +27,9 @@
  */
 
 
-#include "mtypes.h"
-#include "macros.h"
-#include "enums.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "main/enums.h"
 #include "vbo_split.h"
 
 
diff --git a/src/mesa/vf/vf.c b/src/mesa/vf/vf.c
new file mode 100644 (file)
index 0000000..cb25f2e
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2003 Tungsten Graphics, inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to 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 <keithw@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "colormac.h"
+
+#include "vf.h"
+
+#define DBG 0
+
+
+
+static GLboolean match_fastpath( struct vertex_fetch *vf,
+                                const struct vf_fastpath *fp)
+{
+   GLuint j;
+
+   if (vf->attr_count != fp->attr_count) 
+      return GL_FALSE;
+
+   for (j = 0; j < vf->attr_count; j++) 
+      if (vf->attr[j].format != fp->attr[j].format ||
+         vf->attr[j].inputsize != fp->attr[j].size ||
+         vf->attr[j].vertoffset != fp->attr[j].offset) 
+        return GL_FALSE;
+      
+   if (fp->match_strides) {
+      if (vf->vertex_stride != fp->vertex_stride)
+        return GL_FALSE;
+
+      for (j = 0; j < vf->attr_count; j++) 
+        if (vf->attr[j].inputstride != fp->attr[j].stride) 
+           return GL_FALSE;
+   }
+   
+   return GL_TRUE;
+}
+
+static GLboolean search_fastpath_emit( struct vertex_fetch *vf )
+{
+   struct vf_fastpath *fp = vf->fastpath;
+
+   for ( ; fp ; fp = fp->next) {
+      if (match_fastpath(vf, fp)) {
+         vf->emit = fp->func;
+        return GL_TRUE;
+      }
+   }
+
+   return GL_FALSE;
+}
+
+void vf_register_fastpath( struct vertex_fetch *vf,
+                            GLboolean match_strides )
+{
+   struct vf_fastpath *fastpath = CALLOC_STRUCT(vf_fastpath);
+   GLuint i;
+
+   fastpath->vertex_stride = vf->vertex_stride;
+   fastpath->attr_count = vf->attr_count;
+   fastpath->match_strides = match_strides;
+   fastpath->func = vf->emit;
+   fastpath->attr = (struct vf_attr_type *)
+      _mesa_malloc(vf->attr_count * sizeof(fastpath->attr[0]));
+
+   for (i = 0; i < vf->attr_count; i++) {
+      fastpath->attr[i].format = vf->attr[i].format;
+      fastpath->attr[i].stride = vf->attr[i].inputstride;
+      fastpath->attr[i].size = vf->attr[i].inputsize;
+      fastpath->attr[i].offset = vf->attr[i].vertoffset;
+   }
+
+   fastpath->next = vf->fastpath;
+   vf->fastpath = fastpath;
+}
+
+
+
+
+/***********************************************************************
+ * Build codegen functions or return generic ones:
+ */
+static void choose_emit_func( struct vertex_fetch *vf, 
+                             GLuint count, 
+                             GLubyte *dest)
+{
+   vf->emit = NULL;
+   
+   /* Does this match an existing (hardwired, codegen or known-bad)
+    * fastpath?
+    */
+   if (search_fastpath_emit(vf)) {
+      /* Use this result.  If it is null, then it is already known
+       * that the current state will fail for codegen and there is no
+       * point trying again.
+       */
+   }
+   else if (vf->codegen_emit) {
+      vf->codegen_emit( vf );
+   }
+
+   if (!vf->emit) {
+      vf_generate_hardwired_emit(vf);
+   }
+
+   /* Otherwise use the generic version:
+    */
+   if (!vf->emit)
+      vf->emit = vf_generic_emit;
+
+   vf->emit( vf, count, dest );
+}
+
+
+
+
+
+/***********************************************************************
+ * Public entrypoints, mostly dispatch to the above:
+ */
+
+
+
+GLuint vf_set_vertex_attributes( struct vertex_fetch *vf, 
+                                const struct vf_attr_map *map,
+                                GLuint nr, 
+                                GLuint vertex_stride )
+{
+   GLuint offset = 0;
+   GLuint i, j;
+
+   assert(nr < VF_ATTRIB_MAX);
+
+   memset(vf->lookup, 0, sizeof(vf->lookup));
+
+   for (j = 0, i = 0; i < nr; i++) {
+      const GLuint format = map[i].format;
+      if (format == EMIT_PAD) {
+        if (DBG)
+           _mesa_printf("%d: pad %d, offset %d\n", i,  
+                        map[i].offset, offset);  
+
+        offset += map[i].offset;
+
+      }
+      else {
+        assert(vf->lookup[map[i].attrib] == 0);
+        vf->lookup[map[i].attrib] = &vf->attr[j];
+
+        vf->attr[j].attrib = map[i].attrib;
+        vf->attr[j].format = format;
+        vf->attr[j].insert = vf_format_info[format].insert;
+        vf->attr[j].extract = vf_format_info[format].extract;
+        vf->attr[j].vertattrsize = vf_format_info[format].attrsize;
+        vf->attr[j].vertoffset = offset;
+        
+        if (DBG)
+           _mesa_printf("%d: %s, offset %d\n", i,  
+                        vf_format_info[format].name,
+                        vf->attr[j].vertoffset);   
+
+        offset += vf_format_info[format].attrsize;
+        j++;
+      }
+   }
+
+   vf->attr_count = j;
+   vf->vertex_stride = vertex_stride ? vertex_stride : offset;
+   vf->emit = choose_emit_func;
+
+   assert(vf->vertex_stride >= offset);
+   return vf->vertex_stride;
+}
+
+
+
+void vf_set_vp_matrix( struct vertex_fetch *vf,
+                      const GLfloat *viewport )
+{
+   assert(vf->allow_viewport_emits);
+
+   /* scale */
+   vf->vp[0] = viewport[MAT_SX];
+   vf->vp[1] = viewport[MAT_SY];
+   vf->vp[2] = viewport[MAT_SZ];
+   vf->vp[3] = 1.0;
+
+   /* translate */
+   vf->vp[4] = viewport[MAT_TX];
+   vf->vp[5] = viewport[MAT_TY];
+   vf->vp[6] = viewport[MAT_TZ];
+   vf->vp[7] = 0.0;
+}
+
+void vf_set_vp_scale_translate( struct vertex_fetch *vf,
+                               const GLfloat *scale,
+                               const GLfloat *translate )
+{
+   assert(vf->allow_viewport_emits);
+
+   vf->vp[0] = scale[0];
+   vf->vp[1] = scale[1];
+   vf->vp[2] = scale[2];
+   vf->vp[3] = scale[3];
+
+   vf->vp[4] = translate[0];
+   vf->vp[5] = translate[1];
+   vf->vp[6] = translate[2];
+   vf->vp[7] = translate[3];
+}
+
+
+/* Set attribute pointers, adjusted for start position:
+ */
+void vf_set_sources( struct vertex_fetch *vf,
+                    GLvector4f * const sources[],
+                    GLuint start )
+{
+   struct vf_attr *a = vf->attr;
+   GLuint j;
+   
+   for (j = 0; j < vf->attr_count; j++) {
+      const GLvector4f *vptr = sources[a[j].attrib];
+      
+      if ((a[j].inputstride != vptr->stride) ||
+         (a[j].inputsize != vptr->size))
+        vf->emit = choose_emit_func;
+      
+      a[j].inputstride = vptr->stride;
+      a[j].inputsize = vptr->size;
+      a[j].do_insert = a[j].insert[vptr->size - 1]; 
+      a[j].inputptr = ((GLubyte *)vptr->data) + start * vptr->stride;
+   }
+}
+
+
+
+/* Emit count VB vertices to dest.  
+ */
+void vf_emit_vertices( struct vertex_fetch *vf,
+                      GLuint count,
+                      void *dest )
+{
+   vf->emit( vf, count, (GLubyte*) dest );     
+}
+
+
+/* Extract a named attribute from a hardware vertex.  Will have to
+ * reverse any viewport transformation, swizzling or other conversions
+ * which may have been applied.
+ *
+ * This is mainly required for on-the-fly vertex translations to
+ * swrast format.
+ */
+void vf_get_attr( struct vertex_fetch *vf,
+                 const void *vertex,
+                 GLenum attr, 
+                 const GLfloat *dflt,
+                 GLfloat *dest )
+{
+   const struct vf_attr *a = vf->attr;
+   const GLuint attr_count = vf->attr_count;
+   GLuint j;
+
+   for (j = 0; j < attr_count; j++) {
+      if (a[j].attrib == attr) {
+        a[j].extract( &a[j], dest, (GLubyte *)vertex + a[j].vertoffset );
+        return;
+      }
+   }
+
+   /* Else return the value from ctx->Current.
+    */
+   _mesa_memcpy( dest, dflt, 4*sizeof(GLfloat));
+}
+
+
+
+
+struct vertex_fetch *vf_create( GLboolean allow_viewport_emits )
+{
+   struct vertex_fetch *vf = CALLOC_STRUCT(vertex_fetch);
+   GLuint i;
+
+   for (i = 0; i < VF_ATTRIB_MAX; i++)
+      vf->attr[i].vf = vf;
+
+   vf->allow_viewport_emits = allow_viewport_emits;
+
+   switch(CHAN_TYPE) {
+   case GL_UNSIGNED_BYTE:
+      vf->chan_scale[0] = 255.0;
+      vf->chan_scale[1] = 255.0;
+      vf->chan_scale[2] = 255.0;
+      vf->chan_scale[3] = 255.0;
+      break;
+   case GL_UNSIGNED_SHORT:
+      vf->chan_scale[0] = 65535.0;
+      vf->chan_scale[1] = 65535.0;
+      vf->chan_scale[2] = 65535.0;
+      vf->chan_scale[3] = 65535.0;
+      break;
+   default:
+      vf->chan_scale[0] = 1.0;
+      vf->chan_scale[1] = 1.0;
+      vf->chan_scale[2] = 1.0;
+      vf->chan_scale[3] = 1.0;
+      break;
+   }
+
+   vf->identity[0] = 0.0;
+   vf->identity[1] = 0.0;
+   vf->identity[2] = 0.0;
+   vf->identity[3] = 1.0;
+
+   vf->codegen_emit = NULL;
+
+#ifdef USE_SSE_ASM
+   if (!_mesa_getenv("MESA_NO_CODEGEN"))
+      vf->codegen_emit = vf_generate_sse_emit;
+#endif
+
+   return vf;
+}
+
+
+void vf_destroy( struct vertex_fetch *vf )
+{
+   struct vf_fastpath *fp, *tmp;
+
+   for (fp = vf->fastpath ; fp ; fp = tmp) {
+      tmp = fp->next;
+      FREE(fp->attr);
+
+      /* KW: At the moment, fp->func is constrained to be allocated by
+       * _mesa_exec_alloc(), as the hardwired fastpaths in
+       * t_vertex_generic.c are handled specially.  It would be nice
+       * to unify them, but this probably won't change until this
+       * module gets another overhaul.
+       */
+      _mesa_exec_free((void *) fp->func);
+      FREE(fp);
+   }
+   
+   vf->fastpath = NULL;
+   FREE(vf);
+}
diff --git a/src/mesa/vf/vf.h b/src/mesa/vf/vf.h
new file mode 100644 (file)
index 0000000..fc988b9
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2003 Tungsten Graphics, inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to 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 <keithw@tungstengraphics.com>
+ */
+
+#ifndef VF_VERTEX_H
+#define VF_VERTEX_H
+
+#include "mtypes.h"
+#include "m_vector.h"
+
+enum {
+   VF_ATTRIB_POS = 0,
+   VF_ATTRIB_WEIGHT = 1,
+   VF_ATTRIB_NORMAL = 2,
+   VF_ATTRIB_COLOR0 = 3,
+   VF_ATTRIB_COLOR1 = 4,
+   VF_ATTRIB_FOG = 5,
+   VF_ATTRIB_COLOR_INDEX = 6,
+   VF_ATTRIB_EDGEFLAG = 7,
+   VF_ATTRIB_TEX0 = 8,
+   VF_ATTRIB_TEX1 = 9,
+   VF_ATTRIB_TEX2 = 10,
+   VF_ATTRIB_TEX3 = 11,
+   VF_ATTRIB_TEX4 = 12,
+   VF_ATTRIB_TEX5 = 13,
+   VF_ATTRIB_TEX6 = 14,
+   VF_ATTRIB_TEX7 = 15,
+   VF_ATTRIB_VAR0 = 16,
+   VF_ATTRIB_VAR1 = 17,
+   VF_ATTRIB_VAR2 = 18,
+   VF_ATTRIB_VAR3 = 19,
+   VF_ATTRIB_VAR4 = 20,
+   VF_ATTRIB_VAR5 = 21,
+   VF_ATTRIB_VAR6 = 22,
+   VF_ATTRIB_VAR7 = 23,
+   VF_ATTRIB_POINTSIZE = 24,
+   VF_ATTRIB_BFC0 = 25,
+   VF_ATTRIB_BFC1 = 26,
+   VF_ATTRIB_CLIP_POS = 27,
+   VF_ATTRIB_VERTEX_HEADER = 28,
+   VF_ATTRIB_MAX = 29
+};
+
+
+enum vf_attr_format {
+   EMIT_1F,
+   EMIT_2F,
+   EMIT_3F,
+   EMIT_4F,
+   EMIT_2F_VIEWPORT,           /* do viewport transform and emit */
+   EMIT_3F_VIEWPORT,           /* do viewport transform and emit */
+   EMIT_4F_VIEWPORT,           /* do viewport transform and emit */
+   EMIT_3F_XYW,                        /* for projective texture */
+   EMIT_1UB_1F,                        /* for fog coordinate */
+   EMIT_3UB_3F_RGB,            /* for specular color */
+   EMIT_3UB_3F_BGR,            /* for specular color */
+   EMIT_4UB_4F_RGBA,           /* for color */
+   EMIT_4UB_4F_BGRA,           /* for color */
+   EMIT_4UB_4F_ARGB,           /* for color */
+   EMIT_4UB_4F_ABGR,           /* for color */
+   EMIT_4CHAN_4F_RGBA,         /* for swrast color */
+   EMIT_PAD,                   /* leave a hole of 'offset' bytes */
+   EMIT_MAX
+};
+
+struct vf_attr_map {
+   GLuint attrib;
+   enum vf_attr_format format;
+   GLuint offset;
+};
+
+struct vertex_fetch;
+
+void vf_set_vp_matrix( struct vertex_fetch *vf,
+                     const GLfloat *viewport );
+
+void vf_set_vp_scale_translate( struct vertex_fetch *vf,
+                               const GLfloat *scale,
+                               const GLfloat *translate );
+
+GLuint vf_set_vertex_attributes( struct vertex_fetch *vf,
+                                const struct vf_attr_map *map,
+                                GLuint nr, 
+                                GLuint vertex_stride );
+
+void vf_set_sources( struct vertex_fetch *vf,
+                    GLvector4f * const attrib[],
+                    GLuint start ); 
+
+void vf_emit_vertices( struct vertex_fetch *vf,
+                      GLuint count,
+                      void *dest );
+
+void vf_get_attr( struct vertex_fetch *vf,
+                 const void *vertex,
+                 GLenum attr, 
+                 const GLfloat *dflt,
+                 GLfloat *dest );
+
+struct vertex_fetch *vf_create( GLboolean allow_viewport_emits );
+
+void vf_destroy( struct vertex_fetch *vf );
+
+
+
+/***********************************************************************
+ * Internal functions and structs:
+ */
+
+struct vf_attr;
+
+typedef void (*vf_extract_func)( const struct vf_attr *a, 
+                                GLfloat *out, 
+                                const GLubyte *v );
+
+typedef void (*vf_insert_func)( const struct vf_attr *a, 
+                               GLubyte *v, 
+                               const GLfloat *in );
+
+typedef void (*vf_emit_func)( struct vertex_fetch *vf,
+                             GLuint count, 
+                             GLubyte *dest );
+
+
+
+/* Describes how to convert/move a vertex attribute from a vertex
+ * array to a vertex structure.
+ */
+struct vf_attr
+{
+   struct vertex_fetch *vf;
+
+   GLuint format;
+   GLuint inputsize;
+   GLuint inputstride;
+   GLuint vertoffset;      /* position of the attrib in the vertex struct */
+
+   GLuint attrib;          /* which vertex attrib (0=position, etc) */
+   GLuint vertattrsize;    /* size of the attribute in bytes */
+
+   GLubyte *inputptr;
+   const vf_insert_func *insert;
+   vf_insert_func do_insert;
+   vf_extract_func extract;
+};
+
+struct vertex_fetch
+{
+   struct vf_attr attr[VF_ATTRIB_MAX];
+   GLuint attr_count;
+   GLuint vertex_stride;
+
+   struct vf_attr *lookup[VF_ATTRIB_MAX];
+   
+   vf_emit_func emit;
+
+   /* Parameters and constants for codegen:
+    */
+   GLboolean allow_viewport_emits;
+   GLfloat vp[8];              
+   GLfloat chan_scale[4];
+   GLfloat identity[4];
+
+   struct vf_fastpath *fastpath;
+   
+   void (*codegen_emit)( struct vertex_fetch *vf );
+};
+
+
+struct vf_attr_type {
+   GLuint format;
+   GLuint size;
+   GLuint stride;
+   GLuint offset;
+};
+
+struct vf_fastpath {
+   GLuint vertex_stride;
+   GLuint attr_count;
+   GLboolean match_strides;
+
+   struct vf_attr_type *attr;
+
+   vf_emit_func func;
+   struct vf_fastpath *next;
+};
+
+
+void vf_register_fastpath( struct vertex_fetch *vtx,
+                            GLboolean match_strides );
+
+void vf_generic_emit( struct vertex_fetch *vf,
+                       GLuint count,
+                       GLubyte *v );
+
+void vf_generate_hardwired_emit( struct vertex_fetch *vf );
+
+void vf_generate_sse_emit( struct vertex_fetch *vf );
+
+
+struct vf_format_info {
+   const char *name;
+   vf_extract_func extract;
+   vf_insert_func insert[4];
+   const GLuint attrsize;
+};
+
+const struct vf_format_info vf_format_info[EMIT_MAX];
+
+
+#endif
diff --git a/src/mesa/vf/vf_generic.c b/src/mesa/vf/vf_generic.c
new file mode 100644 (file)
index 0000000..68d8d08
--- /dev/null
@@ -0,0 +1,981 @@
+
+/*
+ * Copyright 2003 Tungsten Graphics, inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to 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 <keithw@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "colormac.h"
+#include "simple_list.h"
+
+#include "vf/vf.h"
+
+
+/*
+ * These functions take the NDC coordinates pointed to by 'in', apply the
+ * NDC->Viewport mapping and store the results at 'v'.
+ */
+
+static INLINE void insert_4f_viewport_4( const struct vf_attr *a, GLubyte *v,
+                                        const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = scale[0] * in[0] + trans[0];
+   out[1] = scale[1] * in[1] + trans[1];
+   out[2] = scale[2] * in[2] + trans[2];
+   out[3] = in[3];
+}
+
+static INLINE void insert_4f_viewport_3( const struct vf_attr *a, GLubyte *v,
+                                        const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = scale[0] * in[0] + trans[0];
+   out[1] = scale[1] * in[1] + trans[1];
+   out[2] = scale[2] * in[2] + trans[2];
+   out[3] = 1;
+}
+
+static INLINE void insert_4f_viewport_2( const struct vf_attr *a, GLubyte *v,
+                                        const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = scale[0] * in[0] + trans[0];
+   out[1] = scale[1] * in[1] + trans[1];
+   out[2] =                    trans[2];
+   out[3] = 1;
+}
+
+static INLINE void insert_4f_viewport_1( const struct vf_attr *a, GLubyte *v,
+                                        const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = scale[0] * in[0] + trans[0];
+   out[1] =                    trans[1];
+   out[2] =                    trans[2];
+   out[3] = 1;
+}
+
+static INLINE void insert_3f_viewport_3( const struct vf_attr *a, GLubyte *v,
+                                        const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = scale[0] * in[0] + trans[0];
+   out[1] = scale[1] * in[1] + trans[1];
+   out[2] = scale[2] * in[2] + trans[2];
+}
+
+static INLINE void insert_3f_viewport_2( const struct vf_attr *a, GLubyte *v,
+                                        const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = scale[0] * in[0] + trans[0];
+   out[1] = scale[1] * in[1] + trans[1];
+   out[2] = scale[2] * in[2] + trans[2];
+}
+
+static INLINE void insert_3f_viewport_1( const struct vf_attr *a, GLubyte *v,
+                                        const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = scale[0] * in[0] + trans[0];
+   out[1] =                    trans[1];
+   out[2] =                    trans[2];
+}
+
+static INLINE void insert_2f_viewport_2( const struct vf_attr *a, GLubyte *v,
+                                        const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = scale[0] * in[0] + trans[0];
+   out[1] = scale[1] * in[1] + trans[1];
+}
+
+static INLINE void insert_2f_viewport_1( const struct vf_attr *a, GLubyte *v,
+                                        const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = scale[0] * in[0] + trans[0];
+   out[1] = trans[1];
+}
+
+
+/*
+ * These functions do the same as above, except for the viewport mapping.
+ */
+
+static INLINE void insert_4f_4( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+   out[2] = in[2];
+   out[3] = in[3];
+}
+
+static INLINE void insert_4f_3( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+   out[2] = in[2];
+   out[3] = 1;
+}
+
+static INLINE void insert_4f_2( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+   out[2] = 0;
+   out[3] = 1;
+}
+
+static INLINE void insert_4f_1( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = 0;
+   out[2] = 0;
+   out[3] = 1;
+}
+
+static INLINE void insert_3f_xyw_4( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+   out[2] = in[3];
+}
+
+static INLINE void insert_3f_xyw_err( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   (void) a; (void) v; (void) in;
+   _mesa_exit(1);
+}
+
+static INLINE void insert_3f_3( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+   out[2] = in[2];
+}
+
+static INLINE void insert_3f_2( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+   out[2] = 0;
+}
+
+static INLINE void insert_3f_1( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = 0;
+   out[2] = 0;
+}
+
+
+static INLINE void insert_2f_2( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+}
+
+static INLINE void insert_2f_1( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = 0;
+}
+
+static INLINE void insert_1f_1( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   (void) a;
+
+   out[0] = in[0];
+}
+
+static INLINE void insert_null( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
+{
+   (void) a; (void) v; (void) in;
+}
+
+static INLINE void insert_4chan_4f_rgba_4( const struct vf_attr *a, GLubyte *v, 
+                                          const GLfloat *in )
+{
+   GLchan *c = (GLchan *)v;
+   (void) a;
+   UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
+   UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
+   UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); 
+   UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
+}
+
+static INLINE void insert_4chan_4f_rgba_3( const struct vf_attr *a, GLubyte *v, 
+                                          const GLfloat *in )
+{
+   GLchan *c = (GLchan *)v;
+   (void) a;
+   UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
+   UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
+   UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); 
+   c[3] = CHAN_MAX;
+}
+
+static INLINE void insert_4chan_4f_rgba_2( const struct vf_attr *a, GLubyte *v, 
+                                          const GLfloat *in )
+{
+   GLchan *c = (GLchan *)v;
+   (void) a;
+   UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
+   UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
+   c[2] = 0;
+   c[3] = CHAN_MAX;
+}
+
+static INLINE void insert_4chan_4f_rgba_1( const struct vf_attr *a, GLubyte *v, 
+                                          const GLfloat *in )
+{
+   GLchan *c = (GLchan *)v;
+   (void) a;
+   UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
+   c[1] = 0;
+   c[2] = 0;
+   c[3] = CHAN_MAX;
+}
+
+static INLINE void insert_4ub_4f_rgba_4( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
+}
+
+static INLINE void insert_4ub_4f_rgba_3( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
+   v[3] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_rgba_2( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   v[2] = 0;
+   v[3] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_rgba_1( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   v[1] = 0;
+   v[2] = 0;
+   v[3] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_bgra_4( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
+}
+
+static INLINE void insert_4ub_4f_bgra_3( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
+   v[3] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_bgra_2( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   v[0] = 0;
+   v[3] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_bgra_1( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   v[1] = 0;
+   v[0] = 0;
+   v[3] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_argb_4( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
+}
+
+static INLINE void insert_4ub_4f_argb_3( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
+   v[0] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_argb_2( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
+   v[3] = 0x00;
+   v[0] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_argb_1( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
+   v[2] = 0x00;
+   v[3] = 0x00;
+   v[0] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_abgr_4( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
+}
+
+static INLINE void insert_4ub_4f_abgr_3( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
+   v[0] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_abgr_2( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
+   v[1] = 0x00;
+   v[0] = 0xff;
+}
+
+static INLINE void insert_4ub_4f_abgr_1( const struct vf_attr *a, GLubyte *v, 
+                                        const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
+   v[2] = 0x00;
+   v[1] = 0x00;
+   v[0] = 0xff;
+}
+
+static INLINE void insert_3ub_3f_rgb_3( const struct vf_attr *a, GLubyte *v, 
+                                       const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
+}
+
+static INLINE void insert_3ub_3f_rgb_2( const struct vf_attr *a, GLubyte *v, 
+                                       const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   v[2] = 0;
+}
+
+static INLINE void insert_3ub_3f_rgb_1( const struct vf_attr *a, GLubyte *v, 
+                                       const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   v[1] = 0;
+   v[2] = 0;
+}
+
+static INLINE void insert_3ub_3f_bgr_3( const struct vf_attr *a, GLubyte *v, 
+                                       const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
+}
+
+static INLINE void insert_3ub_3f_bgr_2( const struct vf_attr *a, GLubyte *v, 
+                                       const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   v[0] = 0;
+}
+
+static INLINE void insert_3ub_3f_bgr_1( const struct vf_attr *a, GLubyte *v, 
+                                       const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   v[1] = 0;
+   v[0] = 0;
+}
+
+
+static INLINE void insert_1ub_1f_1( const struct vf_attr *a, GLubyte *v, 
+                                   const GLfloat *in )
+{
+   (void) a;
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+}
+
+
+/***********************************************************************
+ * Functions to perform the reverse operations to the above, for
+ * swrast translation and clip-interpolation.
+ * 
+ * Currently always extracts a full 4 floats.
+ */
+
+static void extract_4f_viewport( const struct vf_attr *a, GLfloat *out, 
+                                const GLubyte *v )
+{
+   const GLfloat *in = (const GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   /* Although included for completeness, the position coordinate is
+    * usually handled differently during clipping.
+    */
+   out[0] = (in[0] - trans[0]) / scale[0];
+   out[1] = (in[1] - trans[1]) / scale[1];
+   out[2] = (in[2] - trans[2]) / scale[2];
+   out[3] = in[3];
+}
+
+static void extract_3f_viewport( const struct vf_attr *a, GLfloat *out, 
+                                const GLubyte *v )
+{
+   const GLfloat *in = (const GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = (in[0] - trans[0]) / scale[0];
+   out[1] = (in[1] - trans[1]) / scale[1];
+   out[2] = (in[2] - trans[2]) / scale[2];
+   out[3] = 1;
+}
+
+
+static void extract_2f_viewport( const struct vf_attr *a, GLfloat *out, 
+                                const GLubyte *v )
+{
+   const GLfloat *in = (const GLfloat *)v;
+   const GLfloat *scale = a->vf->vp;
+   const GLfloat *trans = a->vf->vp + 4;
+   
+   out[0] = (in[0] - trans[0]) / scale[0];
+   out[1] = (in[1] - trans[1]) / scale[1];
+   out[2] = 0;
+   out[3] = 1;
+}
+
+
+static void extract_4f( const struct vf_attr *a, GLfloat *out, const GLubyte *v  )
+{
+   const GLfloat *in = (const GLfloat *)v;
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+   out[2] = in[2];
+   out[3] = in[3];
+}
+
+static void extract_3f_xyw( const struct vf_attr *a, GLfloat *out, const GLubyte *v )
+{
+   const GLfloat *in = (const GLfloat *)v;
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+   out[2] = 0;
+   out[3] = in[2];
+}
+
+
+static void extract_3f( const struct vf_attr *a, GLfloat *out, const GLubyte *v )
+{
+   const GLfloat *in = (const GLfloat *)v;
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+   out[2] = in[2];
+   out[3] = 1;
+}
+
+
+static void extract_2f( const struct vf_attr *a, GLfloat *out, const GLubyte *v )
+{
+   const GLfloat *in = (const GLfloat *)v;
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = in[1];
+   out[2] = 0;
+   out[3] = 1;
+}
+
+static void extract_1f( const struct vf_attr *a, GLfloat *out, const GLubyte *v )
+{
+   const GLfloat *in = (const GLfloat *)v;
+   (void) a;
+   
+   out[0] = in[0];
+   out[1] = 0;
+   out[2] = 0;
+   out[3] = 1;
+}
+
+static void extract_4chan_4f_rgba( const struct vf_attr *a, GLfloat *out, 
+                                  const GLubyte *v )
+{
+   GLchan *c = (GLchan *)v;
+   (void) a;
+
+   out[0] = CHAN_TO_FLOAT(c[0]);
+   out[1] = CHAN_TO_FLOAT(c[1]);
+   out[2] = CHAN_TO_FLOAT(c[2]);
+   out[3] = CHAN_TO_FLOAT(c[3]);
+}
+
+static void extract_4ub_4f_rgba( const struct vf_attr *a, GLfloat *out, 
+                                const GLubyte *v )
+{
+   (void) a;
+   out[0] = UBYTE_TO_FLOAT(v[0]);
+   out[1] = UBYTE_TO_FLOAT(v[1]);
+   out[2] = UBYTE_TO_FLOAT(v[2]);
+   out[3] = UBYTE_TO_FLOAT(v[3]);
+}
+
+static void extract_4ub_4f_bgra( const struct vf_attr *a, GLfloat *out, 
+                                const GLubyte *v )
+{
+   (void) a;
+   out[2] = UBYTE_TO_FLOAT(v[0]);
+   out[1] = UBYTE_TO_FLOAT(v[1]);
+   out[0] = UBYTE_TO_FLOAT(v[2]);
+   out[3] = UBYTE_TO_FLOAT(v[3]);
+}
+
+static void extract_4ub_4f_argb( const struct vf_attr *a, GLfloat *out, 
+                                const GLubyte *v )
+{
+   (void) a;
+   out[3] = UBYTE_TO_FLOAT(v[0]);
+   out[0] = UBYTE_TO_FLOAT(v[1]);
+   out[1] = UBYTE_TO_FLOAT(v[2]);
+   out[2] = UBYTE_TO_FLOAT(v[3]);
+}
+
+static void extract_4ub_4f_abgr( const struct vf_attr *a, GLfloat *out, 
+                                const GLubyte *v )
+{
+   (void) a;
+   out[3] = UBYTE_TO_FLOAT(v[0]);
+   out[2] = UBYTE_TO_FLOAT(v[1]);
+   out[1] = UBYTE_TO_FLOAT(v[2]);
+   out[0] = UBYTE_TO_FLOAT(v[3]);
+}
+
+static void extract_3ub_3f_rgb( const struct vf_attr *a, GLfloat *out, 
+                               const GLubyte *v )
+{
+   (void) a;
+   out[0] = UBYTE_TO_FLOAT(v[0]);
+   out[1] = UBYTE_TO_FLOAT(v[1]);
+   out[2] = UBYTE_TO_FLOAT(v[2]);
+   out[3] = 1;
+}
+
+static void extract_3ub_3f_bgr( const struct vf_attr *a, GLfloat *out, 
+                               const GLubyte *v )
+{
+   (void) a;
+   out[2] = UBYTE_TO_FLOAT(v[0]);
+   out[1] = UBYTE_TO_FLOAT(v[1]);
+   out[0] = UBYTE_TO_FLOAT(v[2]);
+   out[3] = 1;
+}
+
+static void extract_1ub_1f( const struct vf_attr *a, GLfloat *out, const GLubyte *v )
+{
+   (void) a;
+   out[0] = UBYTE_TO_FLOAT(v[0]);
+   out[1] = 0;
+   out[2] = 0;
+   out[3] = 1;
+}
+
+
+const struct vf_format_info vf_format_info[EMIT_MAX] = 
+{
+   { "1f",
+     extract_1f,
+     { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
+     sizeof(GLfloat) },
+
+   { "2f",
+     extract_2f,
+     { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
+     2 * sizeof(GLfloat) },
+
+   { "3f",
+     extract_3f,
+     { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
+     3 * sizeof(GLfloat) },
+
+   { "4f",
+     extract_4f,
+     { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
+     4 * sizeof(GLfloat) },
+
+   { "2f_viewport",
+     extract_2f_viewport,
+     { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2,
+       insert_2f_viewport_2 },
+     2 * sizeof(GLfloat) },
+
+   { "3f_viewport",
+     extract_3f_viewport,
+     { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3,
+       insert_3f_viewport_3 },
+     3 * sizeof(GLfloat) },
+
+   { "4f_viewport",
+     extract_4f_viewport,
+     { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3,
+       insert_4f_viewport_4 }, 
+     4 * sizeof(GLfloat) },
+
+   { "3f_xyw",
+     extract_3f_xyw,
+     { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, 
+       insert_3f_xyw_4 },
+     3 * sizeof(GLfloat) },
+
+   { "1ub_1f",
+     extract_1ub_1f,
+     { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
+     sizeof(GLubyte) },
+
+   { "3ub_3f_rgb",
+     extract_3ub_3f_rgb,
+     { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3,
+       insert_3ub_3f_rgb_3 },
+     3 * sizeof(GLubyte) },
+
+   { "3ub_3f_bgr",
+     extract_3ub_3f_bgr,
+     { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3,
+       insert_3ub_3f_bgr_3 },
+     3 * sizeof(GLubyte) },
+
+   { "4ub_4f_rgba",
+     extract_4ub_4f_rgba,
+     { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, 
+       insert_4ub_4f_rgba_4 },
+     4 * sizeof(GLubyte) },
+
+   { "4ub_4f_bgra",
+     extract_4ub_4f_bgra,
+     { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3,
+       insert_4ub_4f_bgra_4 },
+     4 * sizeof(GLubyte) },
+
+   { "4ub_4f_argb",
+     extract_4ub_4f_argb,
+     { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3,
+       insert_4ub_4f_argb_4 },
+     4 * sizeof(GLubyte) },
+
+   { "4ub_4f_abgr",
+     extract_4ub_4f_abgr,
+     { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3,
+       insert_4ub_4f_abgr_4 },
+     4 * sizeof(GLubyte) },
+
+   { "4chan_4f_rgba",
+     extract_4chan_4f_rgba,
+     { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3,
+       insert_4chan_4f_rgba_4 },
+     4 * sizeof(GLchan) },
+
+   { "pad",
+     NULL,
+     { NULL, NULL, NULL, NULL },
+     0 }
+
+};
+
+
+
+    
+/***********************************************************************
+ * Hardwired fastpaths for emitting whole vertices or groups of
+ * vertices
+ */
+#define EMIT5(NR, F0, F1, F2, F3, F4, NAME)                            \
+static void NAME( struct vertex_fetch *vf,                             \
+                 GLuint count,                                         \
+                 GLubyte *v )                                          \
+{                                                                      \
+   struct vf_attr *a = vf->attr;                               \
+   GLuint i;                                                           \
+                                                                       \
+   for (i = 0 ; i < count ; i++, v += vf->vertex_stride) {             \
+      if (NR > 0) {                                                    \
+        F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr );    \
+        a[0].inputptr += a[0].inputstride;                             \
+      }                                                                        \
+                                                                       \
+      if (NR > 1) {                                                    \
+        F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr );    \
+        a[1].inputptr += a[1].inputstride;                             \
+      }                                                                        \
+                                                                       \
+      if (NR > 2) {                                                    \
+        F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr );    \
+        a[2].inputptr += a[2].inputstride;                             \
+      }                                                                        \
+                                                                       \
+      if (NR > 3) {                                                    \
+        F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr );    \
+        a[3].inputptr += a[3].inputstride;                             \
+      }                                                                        \
+                                                                       \
+      if (NR > 4) {                                                    \
+        F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr );    \
+        a[4].inputptr += a[4].inputstride;                             \
+      }                                                                        \
+   }                                                                   \
+}
+
+   
+#define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
+                                 insert_null, insert_null, NAME)
+
+#define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
+                                     insert_null, NAME)
+   
+#define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
+                                         insert_null, NAME)
+   
+
+EMIT2(insert_3f_viewport_3, insert_4ub_4f_rgba_4, emit_viewport3_rgba4)
+EMIT2(insert_3f_viewport_3, insert_4ub_4f_bgra_4, emit_viewport3_bgra4)
+EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4)
+
+EMIT3(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_viewport4_rgba4_st2)
+EMIT3(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2,  emit_viewport4_bgra4_st2)
+EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2)
+
+EMIT4(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_viewport4_rgba4_st2_st2)
+EMIT4(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, insert_2f_2,  emit_viewport4_bgra4_st2_st2)
+EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2)
+
+
+/* Use the codegen paths to select one of a number of hardwired
+ * fastpaths.
+ */
+void vf_generate_hardwired_emit( struct vertex_fetch *vf )
+{
+   vf_emit_func func = NULL;
+
+   /* Does it fit a hardwired fastpath?  Help! this is growing out of
+    * control!
+    */
+   switch (vf->attr_count) {
+   case 2:
+      if (vf->attr[0].do_insert == insert_3f_viewport_3) {
+        if (vf->attr[1].do_insert == insert_4ub_4f_bgra_4) 
+           func = emit_viewport3_bgra4;
+        else if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) 
+           func = emit_viewport3_rgba4;
+      }
+      else if (vf->attr[0].do_insert == insert_3f_3 &&
+              vf->attr[1].do_insert == insert_4ub_4f_rgba_4) {
+        func = emit_xyz3_rgba4; 
+      }
+      break;
+   case 3:
+      if (vf->attr[2].do_insert == insert_2f_2) {
+        if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) {
+           if (vf->attr[0].do_insert == insert_4f_viewport_4)
+              func = emit_viewport4_rgba4_st2;
+           else if (vf->attr[0].do_insert == insert_4f_4) 
+              func = emit_xyzw4_rgba4_st2;
+        }
+        else if (vf->attr[1].do_insert == insert_4ub_4f_bgra_4 &&
+                 vf->attr[0].do_insert == insert_4f_viewport_4)
+           func = emit_viewport4_bgra4_st2;
+      }
+      break;
+   case 4:
+      if (vf->attr[2].do_insert == insert_2f_2 &&
+         vf->attr[3].do_insert == insert_2f_2) {
+        if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) {
+           if (vf->attr[0].do_insert == insert_4f_viewport_4)
+              func = emit_viewport4_rgba4_st2_st2;
+           else if (vf->attr[0].do_insert == insert_4f_4) 
+              func = emit_xyzw4_rgba4_st2_st2;
+        }
+        else if (vf->attr[1].do_insert == insert_4ub_4f_bgra_4 &&
+                 vf->attr[0].do_insert == insert_4f_viewport_4)
+           func = emit_viewport4_bgra4_st2_st2;
+      }
+      break;
+   }
+
+   vf->emit = func;
+}
+
+/***********************************************************************
+ * Generic (non-codegen) functions for whole vertices or groups of
+ * vertices
+ */
+
+void vf_generic_emit( struct vertex_fetch *vf,
+                     GLuint count,
+                     GLubyte *v )
+{
+   struct vf_attr *a = vf->attr;
+   const GLuint attr_count = vf->attr_count;
+   const GLuint stride = vf->vertex_stride;
+   GLuint i, j;
+
+   for (i = 0 ; i < count ; i++, v += stride) {
+      for (j = 0; j < attr_count; j++) {
+        GLfloat *in = (GLfloat *)a[j].inputptr;
+        a[j].inputptr += a[j].inputstride;
+        a[j].do_insert( &a[j], v + a[j].vertoffset, in );
+      }
+   }
+}
+
+
diff --git a/src/mesa/vf/vf_sse.c b/src/mesa/vf/vf_sse.c
new file mode 100644 (file)
index 0000000..a5d1434
--- /dev/null
@@ -0,0 +1,664 @@
+/*
+ * Copyright 2003 Tungsten Graphics, inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to 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 <keithw@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "colormac.h"
+#include "simple_list.h"
+#include "enums.h"
+
+#include "vf/vf.h"
+
+#if defined(USE_SSE_ASM)
+
+#include "x86/rtasm/x86sse.h"
+#include "x86/common_x86_asm.h"
+
+
+#define X    0
+#define Y    1
+#define Z    2
+#define W    3
+
+
+struct x86_program {
+   struct x86_function func;
+
+   struct vertex_fetch *vf;
+   GLboolean inputs_safe;
+   GLboolean outputs_safe;
+   GLboolean have_sse2;
+   
+   struct x86_reg identity;
+   struct x86_reg chan0;
+};
+
+
+static struct x86_reg get_identity( struct x86_program *p )
+{
+   return p->identity;
+}
+
+static void emit_load4f_4( struct x86_program *p,                         
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   sse_movups(&p->func, dest, arg0);
+}
+
+static void emit_load4f_3( struct x86_program *p, 
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   /* Have to jump through some hoops:
+    *
+    * c 0 0 0
+    * c 0 0 1
+    * 0 0 c 1
+    * a b c 1
+    */
+   sse_movss(&p->func, dest, x86_make_disp(arg0, 8));
+   sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) );
+   sse_shufps(&p->func, dest, dest, SHUF(Y,Z,X,W) );
+   sse_movlps(&p->func, dest, arg0);
+}
+
+static void emit_load4f_2( struct x86_program *p, 
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   /* Initialize from identity, then pull in low two words:
+    */
+   sse_movups(&p->func, dest, get_identity(p));
+   sse_movlps(&p->func, dest, arg0);
+}
+
+static void emit_load4f_1( struct x86_program *p, 
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   /* Pull in low word, then swizzle in identity */
+   sse_movss(&p->func, dest, arg0);
+   sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) );
+}
+
+
+
+static void emit_load3f_3( struct x86_program *p,                         
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   /* Over-reads by 1 dword - potential SEGV if input is a vertex
+    * array.
+    */
+   if (p->inputs_safe) {
+      sse_movups(&p->func, dest, arg0);
+   } 
+   else {
+      /* c 0 0 0
+       * c c c c
+       * a b c c 
+       */
+      sse_movss(&p->func, dest, x86_make_disp(arg0, 8));
+      sse_shufps(&p->func, dest, dest, SHUF(X,X,X,X));
+      sse_movlps(&p->func, dest, arg0);
+   }
+}
+
+static void emit_load3f_2( struct x86_program *p, 
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   emit_load4f_2(p, dest, arg0);
+}
+
+static void emit_load3f_1( struct x86_program *p, 
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   emit_load4f_1(p, dest, arg0);
+}
+
+static void emit_load2f_2( struct x86_program *p, 
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   sse_movlps(&p->func, dest, arg0);
+}
+
+static void emit_load2f_1( struct x86_program *p, 
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   emit_load4f_1(p, dest, arg0);
+}
+
+static void emit_load1f_1( struct x86_program *p, 
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   sse_movss(&p->func, dest, arg0);
+}
+
+static void (*load[4][4])( struct x86_program *p, 
+                          struct x86_reg dest,
+                          struct x86_reg arg0 ) = {
+   { emit_load1f_1, 
+     emit_load1f_1, 
+     emit_load1f_1, 
+     emit_load1f_1 },
+
+   { emit_load2f_1, 
+     emit_load2f_2, 
+     emit_load2f_2, 
+     emit_load2f_2 },
+
+   { emit_load3f_1, 
+     emit_load3f_2, 
+     emit_load3f_3, 
+     emit_load3f_3 },
+
+   { emit_load4f_1, 
+     emit_load4f_2, 
+     emit_load4f_3, 
+     emit_load4f_4 } 
+};
+
+static void emit_load( struct x86_program *p,
+                      struct x86_reg dest,
+                      GLuint sz,
+                      struct x86_reg src,
+                      GLuint src_sz)
+{
+   load[sz-1][src_sz-1](p, dest, src);
+}
+
+static void emit_store4f( struct x86_program *p,                          
+                         struct x86_reg dest,
+                         struct x86_reg arg0 )
+{
+   sse_movups(&p->func, dest, arg0);
+}
+
+static void emit_store3f( struct x86_program *p, 
+                         struct x86_reg dest,
+                         struct x86_reg arg0 )
+{
+   if (p->outputs_safe) {
+      /* Emit the extra dword anyway.  This may hurt writecombining,
+       * may cause other problems.
+       */
+      sse_movups(&p->func, dest, arg0);
+   }
+   else {
+      /* Alternate strategy - emit two, shuffle, emit one.
+       */
+      sse_movlps(&p->func, dest, arg0);
+      sse_shufps(&p->func, arg0, arg0, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */
+      sse_movss(&p->func, x86_make_disp(dest,8), arg0);
+   }
+}
+
+static void emit_store2f( struct x86_program *p, 
+                          struct x86_reg dest,
+                          struct x86_reg arg0 )
+{
+   sse_movlps(&p->func, dest, arg0);
+}
+
+static void emit_store1f( struct x86_program *p, 
+                         struct x86_reg dest,
+                         struct x86_reg arg0 )
+{
+   sse_movss(&p->func, dest, arg0);
+}
+
+
+static void (*store[4])( struct x86_program *p, 
+                        struct x86_reg dest,
+                        struct x86_reg arg0 ) = 
+{
+   emit_store1f, 
+   emit_store2f, 
+   emit_store3f, 
+   emit_store4f 
+};
+
+static void emit_store( struct x86_program *p,
+                       struct x86_reg dest,
+                       GLuint sz,
+                       struct x86_reg temp )
+
+{
+   store[sz-1](p, dest, temp);
+}
+
+static void emit_pack_store_4ub( struct x86_program *p,
+                                struct x86_reg dest,
+                                struct x86_reg temp )
+{
+   /* Scale by 255.0
+    */
+   sse_mulps(&p->func, temp, p->chan0);
+
+   if (p->have_sse2) {
+      sse2_cvtps2dq(&p->func, temp, temp);
+      sse2_packssdw(&p->func, temp, temp);
+      sse2_packuswb(&p->func, temp, temp);
+      sse_movss(&p->func, dest, temp);
+   }
+   else {
+      struct x86_reg mmx0 = x86_make_reg(file_MMX, 0);
+      struct x86_reg mmx1 = x86_make_reg(file_MMX, 1);
+      sse_cvtps2pi(&p->func, mmx0, temp);
+      sse_movhlps(&p->func, temp, temp);
+      sse_cvtps2pi(&p->func, mmx1, temp);
+      mmx_packssdw(&p->func, mmx0, mmx1);
+      mmx_packuswb(&p->func, mmx0, mmx0);
+      mmx_movd(&p->func, dest, mmx0);
+   }
+}
+
+static GLint get_offset( const void *a, const void *b )
+{
+   return (const char *)b - (const char *)a;
+}
+
+/* Not much happens here.  Eventually use this function to try and
+ * avoid saving/reloading the source pointers each vertex (if some of
+ * them can fit in registers).
+ */
+static void get_src_ptr( struct x86_program *p,
+                        struct x86_reg srcREG,
+                        struct x86_reg vfREG,
+                        struct vf_attr *a )
+{
+   struct vertex_fetch *vf = p->vf;
+   struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr));
+
+   /* Load current a[j].inputptr
+    */
+   x86_mov(&p->func, srcREG, ptr_to_src);
+}
+
+static void update_src_ptr( struct x86_program *p,
+                        struct x86_reg srcREG,
+                        struct x86_reg vfREG,
+                        struct vf_attr *a )
+{
+   if (a->inputstride) {
+      struct vertex_fetch *vf = p->vf;
+      struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr));
+
+      /* add a[j].inputstride (hardcoded value - could just as easily
+       * pull the stride value from memory each time).
+       */
+      x86_lea(&p->func, srcREG, x86_make_disp(srcREG, a->inputstride));
+      
+      /* save new value of a[j].inputptr 
+       */
+      x86_mov(&p->func, ptr_to_src, srcREG);
+   }
+}
+
+
+/* Lots of hardcoding
+ *
+ * EAX -- pointer to current output vertex
+ * ECX -- pointer to current attribute 
+ * 
+ */
+static GLboolean build_vertex_emit( struct x86_program *p )
+{
+   struct vertex_fetch *vf = p->vf;
+   GLuint j = 0;
+
+   struct x86_reg vertexEAX = x86_make_reg(file_REG32, reg_AX);
+   struct x86_reg srcECX = x86_make_reg(file_REG32, reg_CX);
+   struct x86_reg countEBP = x86_make_reg(file_REG32, reg_BP);
+   struct x86_reg vfESI = x86_make_reg(file_REG32, reg_SI);
+   struct x86_reg temp = x86_make_reg(file_XMM, 0);
+   struct x86_reg vp0 = x86_make_reg(file_XMM, 1);
+   struct x86_reg vp1 = x86_make_reg(file_XMM, 2);
+   GLubyte *fixup, *label;
+
+   x86_init_func(&p->func);
+   
+   /* Push a few regs?
+    */
+   x86_push(&p->func, countEBP);
+   x86_push(&p->func, vfESI);
+
+
+   /* Get vertex count, compare to zero
+    */
+   x86_xor(&p->func, srcECX, srcECX);
+   x86_mov(&p->func, countEBP, x86_fn_arg(&p->func, 2));
+   x86_cmp(&p->func, countEBP, srcECX);
+   fixup = x86_jcc_forward(&p->func, cc_E);
+
+   /* Initialize destination register. 
+    */
+   x86_mov(&p->func, vertexEAX, x86_fn_arg(&p->func, 3));
+
+   /* Move argument 1 (vf) into a reg:
+    */
+   x86_mov(&p->func, vfESI, x86_fn_arg(&p->func, 1));
+
+   
+   /* Possibly load vp0, vp1 for viewport calcs:
+    */
+   if (vf->allow_viewport_emits) {
+      sse_movups(&p->func, vp0, x86_make_disp(vfESI, get_offset(vf, &vf->vp[0])));
+      sse_movups(&p->func, vp1, x86_make_disp(vfESI, get_offset(vf, &vf->vp[4])));
+   }
+
+   /* always load, needed or not:
+    */
+   sse_movups(&p->func, p->chan0, x86_make_disp(vfESI, get_offset(vf, &vf->chan_scale[0])));
+   sse_movups(&p->func, p->identity, x86_make_disp(vfESI, get_offset(vf, &vf->identity[0])));
+
+   /* Note address for loop jump */
+   label = x86_get_label(&p->func);
+
+   /* Emit code for each of the attributes.  Currently routes
+    * everything through SSE registers, even when it might be more
+    * efficient to stick with regular old x86.  No optimization or
+    * other tricks - enough new ground to cover here just getting
+    * things working.
+    */
+   while (j < vf->attr_count) {
+      struct vf_attr *a = &vf->attr[j];
+      struct x86_reg dest = x86_make_disp(vertexEAX, a->vertoffset);
+
+      /* Now, load an XMM reg from src, perhaps transform, then save.
+       * Could be shortcircuited in specific cases:
+       */
+      switch (a->format) {
+      case EMIT_1F:
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize);
+        emit_store(p, dest, 1, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+      case EMIT_2F:
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize);
+        emit_store(p, dest, 2, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+      case EMIT_3F:
+        /* Potentially the worst case - hardcode 2+1 copying:
+         */
+        if (0) {
+           get_src_ptr(p, srcECX, vfESI, a);
+           emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize);
+           emit_store(p, dest, 3, temp);
+           update_src_ptr(p, srcECX, vfESI, a);
+        }
+        else {
+           get_src_ptr(p, srcECX, vfESI, a);
+           emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize);
+           emit_store(p, dest, 2, temp);
+           if (a->inputsize > 2) {
+              emit_load(p, temp, 1, x86_make_disp(srcECX, 8), 1);
+              emit_store(p, x86_make_disp(dest,8), 1, temp);
+           }
+           else {
+              sse_movss(&p->func, x86_make_disp(dest,8), get_identity(p));
+           }
+           update_src_ptr(p, srcECX, vfESI, a);
+        }
+        break;
+      case EMIT_4F:
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize);
+        emit_store(p, dest, 4, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+      case EMIT_2F_VIEWPORT: 
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize);
+        sse_mulps(&p->func, temp, vp0);
+        sse_addps(&p->func, temp, vp1);
+        emit_store(p, dest, 2, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+      case EMIT_3F_VIEWPORT: 
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize);
+        sse_mulps(&p->func, temp, vp0);
+        sse_addps(&p->func, temp, vp1);
+        emit_store(p, dest, 3, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+      case EMIT_4F_VIEWPORT: 
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize);
+        sse_mulps(&p->func, temp, vp0);
+        sse_addps(&p->func, temp, vp1);
+        emit_store(p, dest, 4, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+      case EMIT_3F_XYW:
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize);
+        sse_shufps(&p->func, temp, temp, SHUF(X,Y,W,Z));
+        emit_store(p, dest, 3, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+
+      case EMIT_1UB_1F:         
+        /* Test for PAD3 + 1UB:
+         */
+        if (j > 0 &&
+            a[-1].vertoffset + a[-1].vertattrsize <= a->vertoffset - 3)
+        {
+           get_src_ptr(p, srcECX, vfESI, a);
+           emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize);
+           sse_shufps(&p->func, temp, temp, SHUF(X,X,X,X));
+           emit_pack_store_4ub(p, x86_make_disp(dest, -3), temp); /* overkill! */
+           update_src_ptr(p, srcECX, vfESI, a);
+        }
+        else {
+           _mesa_printf("Can't emit 1ub %x %x %d\n", a->vertoffset, a[-1].vertoffset, a[-1].vertattrsize );
+           return GL_FALSE;
+        }
+        break;
+      case EMIT_3UB_3F_RGB:
+      case EMIT_3UB_3F_BGR:
+        /* Test for 3UB + PAD1:
+         */
+        if (j == vf->attr_count - 1 ||
+            a[1].vertoffset >= a->vertoffset + 4) {
+           get_src_ptr(p, srcECX, vfESI, a);
+           emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize);
+           if (a->format == EMIT_3UB_3F_BGR)
+              sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W));
+           emit_pack_store_4ub(p, dest, temp);
+           update_src_ptr(p, srcECX, vfESI, a);
+        }
+        /* Test for 3UB + 1UB:
+         */
+        else if (j < vf->attr_count - 1 &&
+                 a[1].format == EMIT_1UB_1F &&
+                 a[1].vertoffset == a->vertoffset + 3) {
+           get_src_ptr(p, srcECX, vfESI, a);
+           emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize);
+           update_src_ptr(p, srcECX, vfESI, a);
+
+           /* Make room for incoming value:
+            */
+           sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z));
+
+           get_src_ptr(p, srcECX, vfESI, &a[1]);
+           emit_load(p, temp, 1, x86_deref(srcECX), a[1].inputsize);
+           update_src_ptr(p, srcECX, vfESI, &a[1]);
+
+           /* Rearrange and possibly do BGR conversion:
+            */
+           if (a->format == EMIT_3UB_3F_BGR)
+              sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X));
+           else
+              sse_shufps(&p->func, temp, temp, SHUF(Y,Z,W,X));
+
+           emit_pack_store_4ub(p, dest, temp);
+           j++;                /* NOTE: two attrs consumed */
+        }
+        else {
+           _mesa_printf("Can't emit 3ub\n");
+        }
+        return GL_FALSE;       /* add this later */
+        break;
+
+      case EMIT_4UB_4F_RGBA:
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize);
+        emit_pack_store_4ub(p, dest, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+      case EMIT_4UB_4F_BGRA:
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize);
+        sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W));
+        emit_pack_store_4ub(p, dest, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+      case EMIT_4UB_4F_ARGB:
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize);
+        sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z));
+        emit_pack_store_4ub(p, dest, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+      case EMIT_4UB_4F_ABGR:
+        get_src_ptr(p, srcECX, vfESI, a);
+        emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize);
+        sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X));
+        emit_pack_store_4ub(p, dest, temp);
+        update_src_ptr(p, srcECX, vfESI, a);
+        break;
+      case EMIT_4CHAN_4F_RGBA:
+        switch (CHAN_TYPE) {
+        case GL_UNSIGNED_BYTE:
+           get_src_ptr(p, srcECX, vfESI, a);
+           emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize);
+           emit_pack_store_4ub(p, dest, temp);
+           update_src_ptr(p, srcECX, vfESI, a);
+           break;
+        case GL_FLOAT:
+           get_src_ptr(p, srcECX, vfESI, a);
+           emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize);
+           emit_store(p, dest, 4, temp);
+           update_src_ptr(p, srcECX, vfESI, a);
+           break;
+        case GL_UNSIGNED_SHORT:
+        default:
+           _mesa_printf("unknown CHAN_TYPE %s\n", _mesa_lookup_enum_by_nr(CHAN_TYPE));
+           return GL_FALSE;
+        }
+        break;
+      default:
+        _mesa_printf("unknown a[%d].format %d\n", j, a->format);
+        return GL_FALSE;       /* catch any new opcodes */
+      }
+      
+      /* Increment j by at least 1 - may have been incremented above also:
+       */
+      j++;
+   }
+
+   /* Next vertex:
+    */
+   x86_lea(&p->func, vertexEAX, x86_make_disp(vertexEAX, vf->vertex_stride));
+
+   /* decr count, loop if not zero
+    */
+   x86_dec(&p->func, countEBP);
+   x86_test(&p->func, countEBP, countEBP); 
+   x86_jcc(&p->func, cc_NZ, label);
+
+   /* Exit mmx state?
+    */
+   if (p->func.need_emms)
+      mmx_emms(&p->func);
+
+   /* Land forward jump here:
+    */
+   x86_fixup_fwd_jump(&p->func, fixup);
+
+   /* Pop regs and return
+    */
+   x86_pop(&p->func, x86_get_base_reg(vfESI));
+   x86_pop(&p->func, countEBP);
+   x86_ret(&p->func);
+
+   vf->emit = (vf_emit_func)x86_get_func(&p->func);
+   return GL_TRUE;
+}
+
+
+
+void vf_generate_sse_emit( struct vertex_fetch *vf )
+{
+   struct x86_program p;   
+
+   if (!cpu_has_xmm) {
+      vf->codegen_emit = NULL;
+      return;
+   }
+
+   _mesa_memset(&p, 0, sizeof(p));
+
+   p.vf = vf;
+   p.inputs_safe = 0;          /* for now */
+   p.outputs_safe = 1;         /* for now */
+   p.have_sse2 = cpu_has_xmm2;
+   p.identity = x86_make_reg(file_XMM, 6);
+   p.chan0 = x86_make_reg(file_XMM, 7);
+
+   x86_init_func(&p.func);
+
+   if (build_vertex_emit(&p)) {
+      vf_register_fastpath( vf, GL_TRUE );
+   }
+   else {
+      /* Note the failure so that we don't keep trying to codegen an
+       * impossible state:
+       */
+      vf_register_fastpath( vf, GL_FALSE );
+      x86_release_func(&p.func);
+   }
+}
+
+#else
+
+void vf_generate_sse_emit( struct vertex_fetch *vf )
+{
+   /* Dummy version for when USE_SSE_ASM not defined */
+}
+
+#endif